C# 是否有一种检查变量/属性值的简单方法?

C# 是否有一种检查变量/属性值的简单方法?,c#,exception-handling,C#,Exception Handling,我想知道是否有一种简单的方法来检查变量/属性值是否符合某些条件 目前,我的代码中最流行的一行代码与此类似: if (string.IsNullOrWhiteSpace(someFileName)) { throw new NullReferenceException("'someFileName' must not be null."); } 然后在catch部分记录异常,并继续执行,以此类推 我不喜欢把这行写得到处都是,而只是更改变量名。如果一个人能写下这样的话那就太好了: Ass

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

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

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);
        // ...
    }
}
我们称之为断言库,它应该这样做:

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."
    }
}
编辑-2

@-很遗憾,我还不能使用C 6

经过一些研究,并受到关于stackoverflow的另外两个问题的启发

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

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,您可以使用调试方法,但是只有在调试模式下编译时才能使用

也许Debug.writelineiboolean,字符串可以满足您的需要吗


如何将属性应用于属性
我认为你应该试试图书馆。对于空保护,您可以找到一个包。所有LIB均可通过Nuget获得

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

因此,NullReferenceExcpetion或NullArgumentException将完全从您的方法中抛出

GitHub的示例:

你的代码

什么被遵守


抛出的异常当然有错误的堆栈跟踪,就像它发生在实用程序方法中一样。这真的很重要吗?堆栈跟踪仍应包括调用它的路径。是否有可能使用C 6?搜索nameof。您自己几乎不应该抛出NullReferenceException。如果需要,您应该抛出ArgumentNullException,但如果该值实际上是对空字符串的引用,则不应该抛出ArgumentNullException。至少您还需要传递变量名:Assert.IsNotNullOrWhiteSpacesomeFileName,someFileName;这就是我实际上希望避免将变量作为字符串传递的原因,因为它容易出错。你重构了一些东西,错误的变量名保持不变。
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)
{
}