有没有办法要求提供给方法的参数不为null?

时间:2009-04-16 00:31:53

标签: c# null methods arguments

是否有更好的方法要求参数在方法中不为null?我一直在检查我的方法所需的任何参数是否为null,如下所示。但我想知道是否有更好的方法。

public void MyMethod(string a, int b)
{
   if(a==null){throw new ArgumentNullException("a");}
   if(b==null){throw new ArgumentNullException("b");}

   //more stuff here
}

5 个答案:

答案 0 :(得分:1)

没有其他更好的方法。这是大量微软库处理这种情况的方式。

您可以随时使用扩展方法使其更清晰。

static IsNullArgument(this Object o, string arg)
{
    if (o == null)
        throw ArgumentNullException(arg);
}

答案 1 :(得分:1)

我个人喜欢CuttingEdge.Conditions。它易于使用,并且使其更具可读性。

答案 2 :(得分:1)

这是我认为C#从C ++倒退的少数领域之一。

在C ++中,你可以写

void foo(Bar& bar) { /*...*/ }

非常清楚地向编译器和其他人表明foo采用了Bar的实际实例。是的,有可能 - 努力 - 传递foo一个空引用,但那不是真正合法的C ++。

您在C#中唯一的“解决方案”是({1}} es class代替,因为.NET中的值类型不能是struct(在您的例如, b 不能是null,因为它是null)。对System.Int32的调用无法编译:

bar()

对于C#而言,使 class A { } struct B { } static void foo(A a) { } static void bar(B b) { } static void Main(string[] args) { foo(null); bar(null); } 引用变得更加困难(看起来很难)是很不错的。例如,F#没有可空类型。

有关此问题的一些有趣评论,请阅读Null References: The Billion Dollar Mistake(和评论)。


编辑: 2013年2月来自Eric Lippert的脚注说“......刚好在C#首次实施时,它总是可以为空的引用类型,......似乎似乎可以实现null来处理任何类型,并且默认情况下引用类型将是不可为空的。我们可以有一个类型系统,其中Nullable<T>是表示“a”的唯一合法方式字符串可以是Nullable<string>“。...”

答案 3 :(得分:0)

Rick Brewster(Paint.NET的作者)发表了关于Fluent API替代方案的博客:

http://blog.getpaint.net/2008/12/06/a-fluent-approach-to-c-parameter-validation/

答案 4 :(得分:0)

您可以编写一些实用程序方法。这是java中的常见模式。

用户代码:

public void MyMethod(string a, int b)
{
    //validate each
    Objects.RequireNotNull(a);
    Objects.RequireNotNull(b);

    //or validate in single line as array 
    Objects.RequireNotNullArray(a, b);
}

实施代码:

public static class Objects
{
    public static T RequireNotNull<T>(T arg)
    {
        if(arg == null)
        {
            throw new ArgumentNullException();
        }
        return arg;
    }

    public static object[] RequireNotNullArray(params object[] args)
    {
        return RequireNotNullArray<object>(args);
    }

    public static T[] RequireNotNullArray<T>(params T[] args)
    {
        Objects.RequireNotNull(args);
        for(int i=0; i<args.Length; i++)
        {
            T arg = args[i];
            if(arg == null)
            {
                throw new ArgumentNullException($"null entry at position:{i}");
            }
        }
        return args;
    }

}

您无法在异常中获取变量名称。但是使用堆栈跟踪和您的源代码,应该可以轻松地进行跟踪。