有没有简单明了的方法来检查变量/属性值?

时间:2014-11-11 09:55:56

标签: c# exception-handling

我想知道是否有一种简短的方法来检查变量/属性值是否与某些条件匹配?

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

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

然后异常会记录在catch部分中并继续执行,依此类推。

我不喜欢在整个地方写这条线,只是更改变量名称。如果一个人可以写下这样的话会很棒:

Assert.IsNotNullOrWhiteSpace(someFileName);

并且它抛出一个异常,说" {my variable}不能为空"可能还有一些其他信息,如父类等,如果您只有日志可用,它们可以帮助您调试代码。

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

这种值检查需要特别在运行时工作,因为我大部分时间检查用户输入,如设置,路径,输入等。

编辑:

我想我应该给出一个我试图实现的例子:

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。

经过一些研究并在stackoverflow上的其他两个问题的启发

How to get Property Value from MemberExpression without .Compile()?

get name of a variable or parameter

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

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

3 个答案:

答案 0 :(得分:0)

您可以使用调试方法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

答案 1 :(得分:0)

答案 2 :(得分:0)

我认为您应该尝试使用Fody library库。对于null-guard,你可以找到一个包here。所有的库都可以通过Nuget获得。

Fody是一种使用&#34;编织&#34;的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)
{
}