是否有一种简单快捷的方法来检查变量/属性值

本文关键字:方法 检查 变量 属性 简单 一种 是否 | 更新日期: 2023-09-27 18:30:07

我想知道是否有一种简单快捷的方法来检查变量/属性值是否符合某些条件?

目前,我的代码中最流行的一行与此类似:

if (string.IsNullOrWhiteSpace(someFileName)) 
{
    throw new NullReferenceException("'someFileName' must not be null.");
}

然后异常被记录在catch部分,执行继续,依此类推

我不喜欢把这行写得到处都是,只更改变量名。如果一个人能写这样的东西就太好了:

Assert.IsNotNullOrWhiteSpace(someFileName);

它抛出了一个异常,说"{my variable}不能为null",可能还有一些额外的信息,比如父类等,如果只有可用的日志,这些信息将帮助您调试代码。

编写这样一个实用程序类时遇到的问题是,抛出的异常当然有错误的堆栈跟踪,就像它发生在实用程序方法中一样,而不是在调用断言函数的方法中。

这种值检查尤其需要在运行时进行,因为我大部分时间都会检查用户输入,如设置、路径、输入等。

编辑:

我想我应该举一个我努力实现的目标的例子:

public class FileExtractor {
    public Form MainForm { get; set; }
    public void ExtractFile(string fileName) {
        Assert.IsNotNullOrWhiteSpace(fileName);
        Assert.IsNotNull(MainForm);
        // ...
    }
}

让我们称之为Assert库应该这样做:

public static Assert {
    public static void IsNotNullOrWhiteSpace(this string value) {
        if (string.IsNullOrWhiteSpace(value)) {
            // throw an exception like it occured in the ExtractFile
            // the message should contain a hint like: "fileName must not be null"
        }
    }
public static void IsNotNull(this object value) {
    if (value == null) {
        // throw an excaption like it occured in the ExtractFile, 
        // the messagge should contain a hint like: "FileExtractor.MainForm must not be null."
    }
}

EDIT-2

@CodeCaster-不幸的是,我还不能使用C#6。

在对堆叠式进行了一些研究之后,受到了另外两个问题的启发

如何在没有.Compilet()的情况下从MemberExpression中获取属性值?

获取变量或参数的名称

到目前为止,我想到了这个:

namespace ExceptionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            object test = null;
            Assert.IsNotNull(() => test);
        }
    }
    static class Assert
    {
        public static void IsNotNull<T>(Expression<Func<T>> expression)
        {
            MemberExpression memberExpr = expression.Body as MemberExpression;
            var constExpr = memberExpr.Expression as ConstantExpression;
            var value = (memberExpr.Member as FieldInfo).GetValue(constExpr.Value);
            if (value == null)
            {
                throw new ArgumentNullException(memberExpr.Member.Name);
            }
        }
    }
}

它几乎满足了我的需要。最后一件事是修改堆栈跟踪,使其指向Main方法,而不是IsNotNull

是否有一种简单快捷的方法来检查变量/属性值

您可以使用调试方法(http://msdn.microsoft.com/en-us/library/System.Diagnostics.Debug_methods%28v=vs.110%29.aspx),但仅在调试模式下编译时才起作用。

也许Debug.WriteLineIf(Boolean, String)能满足您的需求?

http://msdn.microsoft.com/en-us/library/y94y4370%28v=vs.110%29.aspx

如何将属性应用于属性http://msdn.microsoft.com/en-us/library/dd901590(VS.95).aspx

我认为您应该尝试使用Fody库。对于空卫士,你可以在这里找到一个包。所有库都可以通过Nuget获得。

Fody是某种AOP库,它使用"编织"技术来操作程序集的IL并注入额外的代码。

因此NullReferenceExcpetion(或者NullArgumentException)将从您的方法中抛出。

GitHub示例:

您的代码

public void SomeMethod(string arg)
{
    // throws ArgumentNullException if arg is null.
}
public void AnotherMethod([AllowNull] string arg)
{
    // arg may be null here
}

遵守了什么

public void SomeMethod(string arg)
{
    if (arg == null)
    {
        throw new ArgumentNullException("arg");
    }
}
public void AnotherMethod(string arg)
{
}