在构造函数中检查Null

时间:2011-01-25 15:57:37

标签: c# exception-handling null

我真的想要找出易于调试的可重用代码的最佳实践。我在开发人员中遇到了一个我不太了解的常见做法。

public MyConstructor(Object myObject)
{
    if (myObject == null)
        throw new ArgumentNullException("myObject is null.");
    _myObject = myObject;
}

几乎没有必要做这个检查。但我认为这是因为我不完全明白做这项检查的好处是什么。似乎无论如何都会抛出一个null引用异常?我可能错了,我真的很想听听它的一些想法。

谢谢。

9 个答案:

答案 0 :(得分:20)

对于编译器,null是一个合法的构造函数参数。

您的班级可能能够处理myObject的空值。但如果它不能 - 如果你的类在myObject为空时会中断 - 那么检查构造函数就可以fail fast

答案 1 :(得分:3)

在许多情况下传递null对象是完全合法的 - 对于这个类,实现者希望确保您不能创建类的实例,而不传递有效的Object实例,所以以后不得不进行检查 - 这是一个很好的做法,尽早确保这一点,这将在构造函数中。

答案 2 :(得分:2)

如果您在4.0以下,则可以执行以下操作:

 public ctor(IEnjection ninjaWeapon) 
 {
     Contract.Requires<ArgumentNullException>(ninjaWeapon != null);
     this.deadlyWeaponary.Add(ninjaWeapon);
 }

如果你使用旧版本,请引用Microsoft.Contract来做同样的事情。

答案 3 :(得分:1)

编译器不知道对象的值,因此必须在运行时检查它,以确保不会使用空值调用它。

这还取决于您的特定解决方案。你不需要抛出异常,我只会抛出它,如果你不能将该值设为null,如果它是null,那就是一个例外情况。

答案 4 :(得分:1)

我认为通常无法判断是否需要检查空值。这取决于你是否可以使用空值变量。 Null本身并不是一个糟糕的状态。您可能遇到允许变量为空而其他情况不允许的情况。

问问自己是否允许空值是否合理并相应地设计构造函数。

答案 5 :(得分:1)

您可以实现一个简单的ThrowIfNull扩展方法来减少每次编写的代码。 Jon Skeet在他的blog和引用的SO文章here中介绍了这一点。

答案 6 :(得分:0)

您需要显式检查null,因为编译器不知道,但也因为null可以是有效的参数。

答案 7 :(得分:0)

好处是在对象构造时会抛出异常,因此您可以轻松地跟踪代码的哪一部分是罪魁祸首。如果您的代码需要非空myobject值并且您没有在构造函数中验证它,则在使用NullReferenceException时将抛出myObject_并且您必须手动追溯到看看是谁发送了那个空值。

答案 8 :(得分:0)

其他人已经正确地指出 null 参数的传递可能有效也可能无效,具体取决于使用代码的功能。

在不需要 null 参数的地方,从 C# 7.0 开始,可以使用 throw 表达式,这允许我们更简洁地重写 null 检查代码,如下所示示例显示:

public MyConstructor(Object myObject)
{
    _myObject = myObject ?? throw new ArgumentNullException(nameof(myObject));
}

以上会将 _myObject 的值设置为参数 myObject 除非该参数为 null,在这种情况下,ArgumentNullException 将被抛出。