Validation 我是否应该确保参数不是';在函数中使用它们之前是否为空?

Validation 我是否应该确保参数不是';在函数中使用它们之前是否为空?,validation,function,exception,arguments,Validation,Function,Exception,Arguments,标题可能无法真正解释我真正想表达的意思,也无法真正想出一种方式来描述我的意思 我想知道在使用函数之前检查函数接受的参数是否为null或empty是否是一种好的做法。我有一个函数,它只是像这样包装一些散列创建 Public Shared Function GenerateHash(ByVal FilePath As IO.FileInfo) As String If (FilePath Is Nothing) Then Throw New ArgumentN

标题可能无法真正解释我真正想表达的意思,也无法真正想出一种方式来描述我的意思

我想知道在使用函数之前检查函数接受的参数是否为null或empty是否是一种好的做法。我有一个函数,它只是像这样包装一些散列创建

Public Shared Function GenerateHash(ByVal FilePath As IO.FileInfo) As String
        If (FilePath Is Nothing) Then
            Throw New ArgumentNullException("FilePath")
        End If

        Dim _sha As New Security.Cryptography.MD5CryptoServiceProvider
        Dim _Hash = Convert.ToBase64String(_sha.ComputeHash(New IO.FileStream(FilePath.FullName, IO.FileMode.Open, IO.FileAccess.Read)))
        Return _Hash
    End Function
正如您所看到的,我只是将IO.Fileinfo作为参数,在函数的开头,我检查以确保它不是空的

我想知道这是一个好的实践,还是应该让它进入实际的哈希程序,然后抛出异常,因为它是空的


谢谢。

如果NULL是不可接受的输入,则引发异常。您自己,就像您在示例中所做的那样,因此消息很有帮助


处理空输入的另一种方法是依次响应空输入。取决于函数的类型——在上面的示例中,我将保留异常。

如果它是用于面向外部的API,那么我会说您希望检查每个参数,因为输入不可信


但是,如果它只在内部使用,那么输入应该是可信的,您可以为自己保存一堆没有给软件增加价值的代码。

一般来说,我建议在使用公共函数/方法之前验证所有参数是一种好做法,并提前失败,而不是在执行了一半函数之后。在这种情况下,抛出异常是正确的

根据您的方法所做的,尽早失败可能很重要。如果您的方法正在更改类上的实例数据,那么您不希望它更改一半的数据,然后遇到null并引发异常,因为对象的数据可能处于中间状态,也可能是无效状态


如果您使用的是OO语言,那么我建议必须验证公共方法的参数,但对于私有和受保护的方法则不那么重要。我的基本原理是,您不知道公共方法的输入是什么-任何其他代码都可能创建类的实例并调用它的公共方法,并传入意外/无效的数据。但是,私有方法是从类内部调用的,类应该已经验证了内部传递的任何数据

大多数情况下,只要您确信不会忽略异常,让它抛出异常是非常合理的

但是,如果您可以添加一些内容,那么使用更准确的异常包装异常并重新显示它并没有什么坏处。解码“NullPointerException”将比“IllegalArgumentException(“必须提供文件路径”)(或其他)花费稍长的时间

最近,我一直在一个平台上工作,在这个平台上,您必须在测试之前运行一个模糊器。每个堆栈跟踪看起来都像猴子在随机输入垃圾,所以我养成了一直检查参数的习惯


我希望在变量和参数上看到一个“nullable”或“nonull”修饰符,以便编译器可以为您检查。

是的,最好在方法开头验证所有参数,并抛出适当的异常,如ArgumentException、ArgumentNullException或ArgumentOutOfRangeException


如果该方法是私有的,那么只有程序员可以传递无效的参数,那么您可以选择断言每个参数是有效的(Debug .AsExt)而不是SUp.

< P>我最喜欢的C++技术之一是在空指针上调试Debug。这是由高级程序员(以及const correction)灌输给我的,也是我在代码审查中最严格的要求之一。我们从未在没有首先声明指针不是null的情况下解除对指针的引用

调试断言仅对调试目标有效(它在发布时被剥离),因此您在生产中没有额外的开销来测试数千个if。通常,它会抛出异常或触发硬件断点。我们甚至有一些系统会抛出一个带有文件/行信息的调试控制台和一个忽略断言的选项(一次或无限期地用于会话)。这是一个非常好的调试和QA工具(我们可以在testers屏幕上看到带有断言的屏幕截图,以及如果忽略该程序是否继续的信息)


我建议断言代码中的所有不变量,包括意外的空值。若If的性能成为一个问题,那个么找到一种有条件地编译并在调试目标中保持其活动状态的方法。与源代码管理一样,这是一种拯救我的技术,而不是让我悲伤的技术(任何开发技术中最重要的试金石测试)。

如果您正在编写一个公共API,请帮助您的调用者快速找到他们的bug,并检查有效的输入

如果您正在编写一个调用方可能不受信任(或调用方的调用方)的API,请检查有效输入,因为这是良好的安全性


如果您的API只能由受信任的调用者访问,比如C#中的“internal”,那么您就不必编写所有额外的代码。它对任何人都没有用处。

您应该对照您在该函数中对其值所做的一组假设检查所有参数

在您的示例中,如果函数的null参数没有任何意义,并且您假设任何使用函数的人都知道这一点,那么传递null参数将显示某种错误和所采取的某种操作(例如引发异常)。如果你使用断言(正如詹姆斯·法塞特(James Fassett)在我面前说的;-),那么在发布版本中它们不会花费你任何成本。(在调试版本中,它们几乎不需要任何成本)

这同样适用于任何其他假设

如果您生成了错误,那么跟踪错误将比将错误留给标准库例程抛出异常更容易。你将能够