C# 检查方法参数的最佳方法是什么?

C# 检查方法参数的最佳方法是什么?,c#,validation,parameters,C#,Validation,Parameters,我知道两种方法来检查方法的参数,并在需要时抛出异常 1) 检查每个参数中的一个,并在错误时引发异常: public void Method(object parameter1, object parameter2) { if (parameter1 == null) { throw new ArgumentNullException("parameter1"); } if (parameter2 == null) { th

我知道两种方法来检查方法的参数,并在需要时抛出异常

1) 检查每个参数中的一个,并在错误时引发异常:

public void Method(object parameter1, object parameter2)
{
    if (parameter1 == null)
    {
        throw new ArgumentNullException("parameter1");
    }

    if (parameter2 == null)
    {
        throw new ArgumentNullException("parameter2");
    }

    ...
}
2) 一次检查所有参数,并对所有参数引发相同的异常:

public void Method(object parameter1, object parameter2)
{
    if (parameter1 == null || parameter2 == null)
    {
        throw new ArgumentNullException();
    }

    ...
}
在我看来,第一种方法更好、更干净,但也涵盖了很多方面。例如,一个实际执行2行代码的方法-这样,每个参数的代码将增加4行(包括空行)


我感兴趣的是有经验的程序员所使用的方法。有比这两种更好的方法吗?

我认为方法1更有用
NullReferenceException
s,或者在本例中,在无法确定什么是
null
的情况下抛出的
ArgumentNullException
s非常令人沮丧


另外,如果您不喜欢查看验证代码,您可以将其包装在代码区域中,并在IDE中折叠起来。

使用method属性来干净地检查参数。
我用python编写了一个参数验证框架。c#最佳实践是

它取决于实际需要什么

  • 若您需要为两个空值抛出不同的异常,那个么您应该使用第一种方法

  • 如果您的代码的两个空情况完全相同,那么第二种方法的可读性更好


  • 就我个人而言,我通常使用检查或验证代码的方法,失败时返回false(可能记录/显示错误)

    我喜欢检查所有问题并验证所有问题,因此使用| |基本上会在第一次测试时停止。

    于2020年7月更新

    查看这篇关于如何实现代码契约类似方法的博客文章

    原始答复如下

    --

    如果您使用的是.NETFramework4,请查看,它将其简化为一行代码

    public string Reverse(string text)
    {
       Contract.Requires<ArgumentNullException>(text!=null, "ParAmeter cannot be null.");
      
       .....
    }
    
    编译器将警告您这将引发异常


    注意:代码契约需要安装外接程序,但它是免费的。

    任何一种方法都可以。基本上,在这里抛出一个
    ArgumentNullException
    是正确的做法

    正如它所说的


    null引用(Visual Basic中没有任何内容)传递给不接受它作为有效参数的方法时引发的异常。

    我知道这是一个旧线程,但我希望共享MHO。这是我通常做的:

    创建泛型方法:

    private void ValidateArgument<exType>(Func<bool> validation, string errorMessage) where exType : Exception
            {
                if (validation())
                {
                    throw Activator.CreateInstance(typeof(exType), errorMessage) as exType;
                }
            }
    
    private void ValidateArgument(Func验证,string errorMessage),其中exttype:Exception
    {
    if(验证())
    {
    抛出Activator.CreateInstance(typeof(exType),errorMessage)作为exType;
    }
    }
    
    然后从调用方法执行以下操作:

    this.ValidateArgument<ArgumentException>(() => string.IsNullOrEmpty(firstname), "firstname must be supplied");
    
    this.ValidateArgument(()=>string.IsNullOrEmpty(firstname),“必须提供firstname”);
    
    就个人而言,我更喜欢第一个示例,因为它更好地解释了错误ArgumentNullException在与此构造函数一起使用时更有用-这样您将看到实际的参数名称。这迫使您使用方法#1如果您想在较旧的样式中执行此操作(如果/那么参数验证),最好单独验证参数,对每个参数进行单独检查。所以从技术上讲,null的测试应该是string.Length==0的另一个检查。如果您开始有大量的验证(5或以上),请考虑使用分离的方法来执行这些验证,并从中抛出异常。请参阅Microsoft关于“验证公共方法的参数”主题的建议。如果参数不多,并且您使用的是旧的.NeT FWNever catch NullReferenceException,则可以使用Reflection获取参数名称,并在一条语句中解决所有问题。@HansPassant by catch我的意思是检测错误。我没有说“或是为了抓住错误”。我只是把括号里的意思讲清楚了。无论如何,我真愚蠢,竟然澄清了这样一件蠢事。让我编辑一下…很好…完全忘了它们。这里是链接,感谢提醒代码合同!我一定会试试。另外,要指出的是,如果您有像第一个示例一样的预先存在的代码,并且您希望开始实现代码契约,您可以通过在代码块后面放置'Contract.EndContractBlock()'语句来告诉编译器代码块已经实现了,现在它将自动集成这些检查。请注意,代码契约实际上已经失效,微软同意。几个月前我发现了这个博客,它对任何想做类似事情的人都很有用。我认为NullReferenceExceptions最好留给取消引用null对象时使用。对不起,我不是很清楚。我完全同意在参数检查中,
    ArgumentNullException
    用于指示空参数。我只是想和看到一个抛出的NRE进行比较,在那里,哪个引用是
    null
    ,是不明确的。谢谢你的链接!但我认为在.NET framework 4中使用代码契约是更好的解决方案。@mveith实际上,如果您查看其他语言中的契约,它们是使用属性实现的。也许这在C#now中已经存在,但我不确定。于是我发现了这个问题。
    this.ValidateArgument<ArgumentException>(() => string.IsNullOrEmpty(firstname), "firstname must be supplied");