C# 检查构造函数中的Null
我真的在试图找出易于调试的可重用代码的最佳实践。我在开发人员中遇到了一个我还不太了解的常见做法C# 检查构造函数中的Null,c#,exception-handling,null,C#,Exception Handling,Null,我真的在试图找出易于调试的可重用代码的最佳实践。我在开发人员中遇到了一个我还不太了解的常见做法 public MyConstructor(Object myObject) { if (myObject == null) throw new ArgumentNullException("myObject is null."); _myObject = myObject; } 几乎没有必要做这项检查。但我认为这是因为我不完全明白做这个检查的好处是什么。似乎无论如何都
public MyConstructor(Object myObject)
{
if (myObject == null)
throw new ArgumentNullException("myObject is null.");
_myObject = myObject;
}
几乎没有必要做这项检查。但我认为这是因为我不完全明白做这个检查的好处是什么。似乎无论如何都会抛出空引用异常?我可能错了,真的很想听听大家的想法
谢谢。编译器不知道对象的值,因此您必须在运行时对此进行检查,以确保不会使用空值调用它
这还取决于您的特定解决方案。你不需要抛出异常,我只会在你不能让该值为null的情况下抛出异常,如果它为null,那就是一个例外情况。我认为,一般来说,不可能判断是否需要检查null。这完全取决于您是否能够使用空值变量。Null本身并不是一个坏状态。在某些情况下,允许变量为null,而在其他情况下则不允许
问问自己是否允许空值并相应地设计构造函数是有意义的。传递一个
null
对象在许多情况下是完全合法的-对于这个类,实现者希望确保您不能创建一个不传递有效对象
实例的类实例,因此以后不必进行检查-最好尽早确保这一点,这将在构造函数中进行。您需要显式检查null,因为编译器不知道,但也因为null可以是有效参数。对于编译器来说,null
是合法的构造函数参数
您的类可能能够为
myObject
处理空值。但是如果不能,如果你的类在myObject
为空时会中断,那么签入构造函数就允许你这样做。好处是异常将在对象构造时抛出,因此你可以很容易地跟踪代码的哪一部分是罪魁祸首。如果您的代码需要非空的myobject
值,并且您没有在构造函数中验证它,当您使用myObject\uu
时,将抛出NullReferenceException
,您必须手动回溯以查看是谁发送了该空值。您可以实现一个简单的ThrowIfNull
扩展方法来减少每次编写的代码。Jon Skeet在其及其引用的SO文章中介绍了这一点。如果您低于4.0,您可以执行以下操作:
public ctor(IEnjection ninjaWeapon)
{
Contract.Requires<ArgumentNullException>(ninjaWeapon != null);
this.deadlyWeaponary.Add(ninjaWeapon);
}
public-ctor(IEnjection-ninja)
{
契约。要求(Ninja武器!=null);
这个。致命武器。添加(忍者武器);
}
如果您使用的是旧版本,请参考Microsoft.Contract来执行相同的操作。其他人已经正确地指出,
null
参数的传递可能有效,也可能无效,这取决于使用代码的功能
如果不需要null
参数,则可以从C#7.0中使用抛出表达式,使我们能够更简洁地重写null
检查代码,如下例所示:
public MyConstructor(Object myObject)
{
_myObject = myObject ?? throw new ArgumentNullException(nameof(myObject));
}
上面将
\u myObject
的值设置为参数myObject
,除非该参数为null
,在这种情况下,将抛出ArgumentNullException
。不需要您执行的操作,您可以在引用对象之前检查以确保该对象不为null。当然,验证对象初始化时将使用的内容是一种非常有效的方法。@Ramhound-这是使用DI框架(如StructureMap)时的一种常见方法,您不必直接控制传递给构造函数的内容。如果您的类没有myObject
是无用的,并且这是初始化它的唯一地方,那么尽早抛出异常是有意义的,这样您就可以了解它们。在一个长时间运行的web应用程序中,你可能不知道这个问题,直到有人碰巧调用了一个需要该对象的方法。解释得很好。我特别喜欢“快速失败”这个词。谢谢你的见解。博客链接断开了,但我想这是同一篇文章:但如果代码契约没有在编译后的步骤中重写,它们将一事无成。