Jas*_*ker 59 .net c# exception-handling exception
假设我有一个方法将某种对象作为参数.现在说如果这个方法传递一个null参数,那就是一个致命的错误,应该抛出一个异常.编写这样的代码对我来说是否值得(请记住这是一个简单的例子):
void someMethod(SomeClass x)
{
if (x == null){
throw new ArgumentNullException("someMethod received a null argument!");
}
x.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
或者,当它调用x.doSomething()时,依赖它抛出NullException是否安全?
其次,假设someMethod是一个构造函数,在调用另一个方法之前不会使用x.我应该立即抛出异常还是等到需要x然后抛出异常?
tva*_*son 60
我喜欢ArgumentNullException过NullReferenceException,不是检查参数将提供.通常,我的首选是在尝试在潜在的null对象上调用方法之前始终检查null.
如果该方法是构造函数,那么它将取决于几个不同的因素:是否还有该属性的公共setter以及该对象实际使用的可能性.如果有一个公共setter,那么不通过构造函数提供有效的实例是合理的,不应该导致异常.
如果没有公共setter并且可以在不引用注入对象的情况下使用包含对象,则可能需要推迟检查/异常,直到尝试使用它为止.我认为一般情况下,注入的对象对于实例的运行至关重要,因此ArgumentNull异常是完全合理的,因为没有它,实例就无法运行.
Chr*_*sic 31
我总是遵循快速失败的做法.如果您的方法依赖于X并且您理解X可能以null传递,则检查它并立即引发异常而不是延长故障点.
2016年更新:
现实世界的例子.我强烈建议使用Jetbrains Annotations.
[Pure]
public static object Call([NotNull] Type declaringType,
[NotNull] string methodName,
[CanBeNull] object instance)
{
if (declaringType == null) throw new ArgumentNullException(nameof(declaringType));
if (methodName == null) throw new ArgumentNullException(nameof(methodName));
Run Code Online (Sandbox Code Playgroud)
C#6为nameof操作员提供了大大改进的防护声明.
viv*_*una 18
我强烈同意@tvanfosson 的观点。添加到他的答案中,使用 .net 6 it\xe2\x80\x99s 很容易抛出ArgumentNullException.
ArgumentNullException.ThrowIfNull(object);\nRun Code Online (Sandbox Code Playgroud)\n这里\xe2\x80\x99是官方文档。
\nJoe*_*orn 14
出于以下原因,我更喜欢显式异常:
And*_*are 11
我同意快速失败的想法 - 然而,明智的是,为什么快速失败是切实可行的.考虑这个例子:
void someMethod(SomeClass x)
{
x.Property.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
如果你依靠NullReferenceException告诉你出了什么问题,你怎么知道什么是空的?堆栈跟踪只会为您提供行号,而不是哪个引用为空.在这个例子中,x或者x.Property两者都可以为空并且没有事先通过激进检查快速失败,你将不知道它是什么.
我更喜欢使用显式ArgumentNullException进行参数检查.
查看元数据:
//
// Summary:
// Initializes a new instance of the System.ArgumentNullException class with
// the name of the parameter that causes this exception.
//
// Parameters:
// paramName:
// The name of the parameter that caused the exception.
public ArgumentNullException(string paramName);
Run Code Online (Sandbox Code Playgroud)
你可以看到,字符串应该是参数的名称,即null,因此给开发人员一个关于出错的提示.
这些天没有理由不进行检查。C# 已经向前发展,您可以使用丢弃和空合并运算符非常巧妙地做到这一点:
_ = declaringType ?? throw new ArgumentNullException(nameof(declaringType));
_ = methodname ?? throw new ArgumentNullException(nameof(methodName));
Run Code Online (Sandbox Code Playgroud)
如果您希望输入不为null,则应显式抛出ArgumentNullException.您可能希望编写一个名为Guard的类,为此提供帮助方法.所以你的代码将是:
void someMethod(SomeClass x, SomeClass y)
{
Guard.NotNull(x,"x","someMethod received a null x argument!");
Guard.NotNull(y,"y","someMethod received a null y argument!");
x.doSomething();
y.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
NonNull方法将执行nullity检查并抛出NullArgumentException,并在调用中指定错误消息.
| 归档时间: |
|
| 查看次数: |
61593 次 |
| 最近记录: |