6

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

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

   //more stuff here
}
4

5 回答 5

2

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

}

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

于 2018-12-15T06:14:05.063 回答
1

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

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

static IsNullArgument(this Object o, string arg)
{
    if (o == null)
        throw ArgumentNullException(arg);
}
于 2009-04-16T00:34:13.837 回答
1

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

于 2009-04-16T00:42:15.363 回答
1

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

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

于 2009-04-16T00:47:37.737 回答
1

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

在 C++ 中,您可以编写

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

非常清楚地向编译器和其他foo采用Bar. 是的,有可能——通过努力——传递foo一个空引用,但这不是真正合法的 C++。

您在 C# 中唯一的“解决方案”(各种)是让您的classesstruct代替,因为 .NET 中的值类型不能null(在您的示例中,b永远不可能null,因为它是 a System.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);
    }

null对于 C# 来说,让引用变得(非常)更加困难,这当然会很好。例如,F# 没有可为空的类型。

有关此问题的一些有趣评论,请阅读空参考:十亿美元的错误(和评论)。


编辑:Eric Lippert在 2013 年 2 月的脚注中说“......碰巧当 C# 首次实现时,它具有始终可以为空的引用类型,......似乎Nullable<T>可以实现任何类型的工作,并且引用类型默认是不可为空的。我们可以有一个类型系统,这Nullable<string>是唯一合法的方式来表示“可以是null”的字符串。...“

于 2009-04-16T01:13:18.190 回答