我真的想要找出易于调试的可重用代码的最佳实践。我在开发人员中遇到了一个我不太了解的常见做法。
public MyConstructor(Object myObject)
{
if (myObject == null)
throw new ArgumentNullException("myObject is null.");
_myObject = myObject;
}
几乎没有必要做这个检查。但我认为这是因为我不完全明白做这项检查的好处是什么。似乎无论如何都会抛出一个null引用异常?我可能错了,我真的很想听听它的一些想法。
谢谢。
答案 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)
答案 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
将被抛出。