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

C# 有没有办法要求提供给方法的参数不为null?,c#,null,methods,arguments,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 } 没有其他更好的办法了。

有没有更好的方法要求方法中的参数不为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
}

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

您始终可以使用扩展方法使其更加清晰

static IsNullArgument(this Object o, string arg)
{
    if (o == null)
        throw ArgumentNullException(arg);
}
我个人喜欢。它易于使用,并使其更具可读性。

Rick Brewster(Paint.NET的作者)在博客中介绍了一种Fluent API替代方案:


< /P> < P>这是我认为C从C++中倒退的几个区域之一。< /P> 在C++中,你可以写< /p>

void foo(Bar& bar) { /*...*/ }
非常清楚地向编译器和其他人表明
foo
实际使用了
Bar
。是的,有可能——通过努力——通过<代码> Foo一个空引用,但这不是真正合法的C++。 在C#中,您唯一的“解决方案”(排序)是使您的
es
struct
s,因为.NET中的值类型不能为
null
(在您的示例中,b永远不能为
null
,因为它是
系统.Int32
)。调用
bar()
将不会编译:

    class A { }
    struct B { }

    static void foo(A a) { }
    static void bar(B b) { }

    static void Main(string[] args)
    {
        foo(null);
        bar(null);
    }
对于C来说,让
null
reference变得(更加)困难显然是件好事;例如,F#没有可为空的类型

有关这件事的一些有趣的评论,请阅读(和评论)



编辑:萨伊2013年2月的脚注"... 碰巧的是,当C#首次实现时,它总是具有可为空的引用类型。。。
Nullable
可以被实现用于任何类型,引用类型在默认情况下是不可为null的,这似乎是合理的。我们可以有一个类型系统,其中
null
是表示“可以
null
的字符串”的唯一合法方式。。。“

您可以编写一些实用程序方法。这是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;
    }

}
公共静态类对象
{
公共静态T要求完整(T参数)
{
如果(arg==null)
{
抛出新ArgumentNullException();
}
返回arg;
}
公共静态对象[]RequireNotNullArray(参数对象[]args)
{
返回要求返回数组(args);
}
公共静态T[]RequireNotNullArray(参数T[]args)
{
对象。RequireNotNull(args);

对于(int i=0;它几乎与以下内容完全相同: