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

发布于 2024-07-17 07:47:22 字数 270 浏览 6 评论 0原文

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

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

   //more stuff here
}

Is there a better way to require that an argument is not null in a method? I keep checking if any of the arguments that my method requires are null, as show below. But I'm wondering if there is a better way.

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

   //more stuff here
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柠檬色的秋千 2024-07-24 07:47:22

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

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

Rick Brewster (author of Paint.NET) blogged about a Fluent API alternative:

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

北方的巷 2024-07-24 07:47:22

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

}

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

You can write some utility methods. This is the common pattern in java.

user code:

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);
}

implementation code:

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;
    }

}

You cannot get the variable name in the exception. but with the stack trace and your source code, it should be possible to easily track down.

往日 2024-07-24 07:47:22

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

I personally like CuttingEdge.Conditions. It's easy to use, and makes this much more readable.

我做我的改变 2024-07-24 07:47:22

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

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

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

There is no other better way. This is the way a ton of Microsoft libraries handle the situation.

You can always use an extension method to make it a little clearer.

static IsNullArgument(this Object o, string arg)
{
    if (o == null)
        throw ArgumentNullException(arg);
}
霞映澄塘 2024-07-24 07:47:22

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

在 C++ 中,您可以

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

清楚地向编译器和其他人表明 foo 采用了 Bar 的实际实例。 是的,通过努力,可以向 foo 传递一个空引用,但这并不是真正合法的 C++。

C# 中唯一的“解决方案”(某种程度上)是让您的 class 成为 struct,因为 .NET 中的值类型不能为 null< /code> (在您的示例中,b 永远不能为 null,因为它是 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);
    }

对于 C# 来说,如果能够让 null 引用变得(更加)困难,那就太好了; 例如,F# 没有可为 null 的类型。

有关此事的一些有趣评论,请阅读 Null参考文献:十亿美元的错误(以及评论)。


编辑: 2013 年 2 月脚注,来自 Eric Lippert< /a> 说“...碰巧的是,当 C# 首次实现时,它具有始终可为空的引用类型,...似乎可以实现 Nullable 来工作在任何类型上,默认情况下引用类型都是不可为空的,其中 Nullable 是表示“可以是 的字符串”的唯一合法方式。空“....”

This is one of the few areas where I think C# went backwards from C++.

In C++, you could write

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

to quite clearly indicate to both the compiler and other humans that foo took an actual instance of Bar. Yes, it is possible--with effort--to pass foo a null reference but that's not really legal C++.

Your only "solution" (of sorts) in C# is to make your classes structs instead, as value types in .NET can't be null (in your example, b can't ever be null because it is a System.Int32). The call to bar() will not compile:

    class A { }
    struct B { }

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

    static void Main(string[] args)
    {
        foo(null);
        bar(null);
    }

It certainly seems like it would have been nice for C# to have made it (much) more difficult to have null references; F#, for example, has no nullable types.

For some interesting commentary related to this matter, read Null References: The Billion Dollar Mistake (and the comments).


Edit: A February 2013 footnote from Eric Lippert says "... it just so happened that when C# was first implemented it had always-nullable reference types, ... it seems plausible that Nullable<T> could have been implemented to work on any type, and reference types would then be non-nullable by default. We could have a type system where Nullable<string> was the only legal way to represent "a string that can be null". ... "

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文