什么是NullReferenceException,我该如何解决?

我有一些代码,当它执行时,它抛出一个NullReferenceException,说:

你调用的对象是空的。

这是什么意思,我该怎么做才能解决这个错误?


Helenr
浏览 9813回答 15
15回答

收到一只叮咚

这意味着有问题的变量没有任何意义。我可以这样生成:SqlConnection connection = null;connection.Open();这将抛出错误,因为当我声明变量“ connection”时,它没有指向任何东西。当我尝试调用成员“ Open”时,没有引用它来解决它,它将抛出错误。要避免此错误:在尝试对它们执行任何操作之前始终初始化对象。如果您不确定对象是否为null,请检查它object == null。JetBrains的Resharper工具将识别代码中可能存在空引用错误的每个位置,允许您进行空检查。这个错误是错误的头号来源,恕我直言。

有只小跳蛙

请注意,无论情况如何,.NET中的原因始终相同:您正在尝试使用值为Nothing/ 的引用变量null。当值为Nothing/ null为引用变量时,这意味着它实际上并未持有对堆上存在的任何对象的实例的引用。您从未向变量分配内容,从未创建分配给变量的值的实例,或者您将变量设置为Nothing/ nullmanual,或者您调用了将变量设置为Nothing/ 的函数null。

繁花不似锦

您正在使用包含空值引用的对象。所以它给出了一个null异常。在示例中,字符串值为null,并且在检查其长度时,发生了异常。例:string&nbsp;value&nbsp;=&nbsp;null;if&nbsp;(value.Length&nbsp;==&nbsp;0)&nbsp;//&nbsp;<--&nbsp;Causes&nbsp;exception{ &nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(value);&nbsp;//&nbsp;<--&nbsp;Never&nbsp;reached}异常错误是:未处理的异常:System.NullReferenceException:未将对象引用设置为对象的实例。在Program.Main()

动漫人物

Simon Mourier举了这个例子:object&nbsp;o&nbsp;=&nbsp;null;DateTime&nbsp;d&nbsp;=&nbsp;(DateTime)o;&nbsp;&nbsp;//&nbsp;NullReferenceException其中一个开箱转换(CAST)从&nbsp;object(或从其中一个类System.ValueType或System.Enum,或从一个接口类型)到一个值类型(比其它Nullable<>本身)给出NullReferenceException。在另一个方向上,一拳击转换从一个Nullable<>具有HasValue等于false&nbsp;以引用类型,可以给一个null参考其然后可以在以后导致NullReferenceException。经典的例子是:DateTime?&nbsp;d&nbsp;=&nbsp;null;var&nbsp;s&nbsp;=&nbsp;d.ToString();&nbsp;&nbsp;//&nbsp;OK,&nbsp;no&nbsp;exception&nbsp;(no&nbsp;boxing),&nbsp;returns&nbsp;""var&nbsp;t&nbsp;=&nbsp;d.GetType();&nbsp;&nbsp; &nbsp;//&nbsp;Bang!&nbsp;d&nbsp;is&nbsp;boxed,&nbsp;NullReferenceException有时拳击以另一种方式发生。例如,使用这种非泛型扩展方法:public&nbsp;static&nbsp;void&nbsp;MyExtension(this&nbsp;object&nbsp;x){ &nbsp;&nbsp;x.ToString();}以下代码将有问题:DateTime?&nbsp;d&nbsp;=&nbsp;null;d.MyExtension();&nbsp;&nbsp;//&nbsp;Leads&nbsp;to&nbsp;boxing,&nbsp;NullReferenceException&nbsp;occurs&nbsp;inside&nbsp;the&nbsp;body&nbsp;of&nbsp;the&nbsp;called&nbsp;method,&nbsp;not&nbsp;here.出现这些情况是因为运行时在装箱Nullable<>实例时使用的特殊规则。

慕码人8056858

我对回答这个问题有不同的看法。这种答案“我还能做些什么来避免它?&nbsp;”当跨不同层工作时,例如在MVC应用程序中,控制器需要服务来调用业务操作。在这种情况下,可以使用Dependency Injection Container初始化服务以避免NullReferenceException。这意味着您不必担心检查null并且只需从控制器调用服务,就好像它们总是可用(并初始化)为单例或原型。public&nbsp;class&nbsp;MyController{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ServiceA&nbsp;serviceA; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ServiceB&nbsp;serviceB; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;MyController(ServiceA&nbsp;serviceA,&nbsp;ServiceB&nbsp;serviceB) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.serviceA&nbsp;=&nbsp;serviceA; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.serviceB&nbsp;=&nbsp;serviceB; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;MyMethod() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;We&nbsp;don't&nbsp;need&nbsp;to&nbsp;check&nbsp;null&nbsp;because&nbsp;the&nbsp;dependency&nbsp;injection&nbsp;container&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;injects&nbsp;it,&nbsp;provided&nbsp;you&nbsp;took&nbsp;care&nbsp;of&nbsp;bootstrapping&nbsp;it. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;someObject&nbsp;=&nbsp;serviceA.DoThis(); &nbsp;&nbsp;&nbsp;&nbsp;}}

米脂

关于“我该怎么办”,可以有很多答案。在开发过程中防止此类错误情况的更“正式”方法是在代码中按合同设计。这意味着您需要在开发时在系统上设置类不变量,和/或甚至函数/方法前置条件和后置条件。简而言之,类不变量确保您的类中存在一些在正常使用中不会被违反的约束(因此,类不会处于不一致状态)。前提条件意味着作为函数/方法的输入给出的数据必须遵循一些约束集并且永远不违反它们,并且后置条件意味着函数/方法输出必须再次遵循设置约束而不违反它们。在执行无错误程序期间永远不应违反合同条件,因此在调试模式下实际检查合同设计,同时在发布中禁用合同条件,以最大化已开发的系统性能。这样,您可以避免NullReferenceException违反约束集的情况。例如,如果X在类中使用对象属性,稍后尝试调用其中一个方法并且X具有空值,则会导致NullReferenceException:public&nbsp;X&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}public&nbsp;void&nbsp;InvokeX(){ &nbsp;&nbsp;&nbsp;&nbsp;X.DoSomething();&nbsp;//&nbsp;if&nbsp;X&nbsp;value&nbsp;is&nbsp;null,&nbsp;you&nbsp;will&nbsp;get&nbsp;a&nbsp;NullReferenceException}但是如果你设置“属性X必须永远不会有空值”作为方法前置条件,那么你可以阻止前面描述的场景://Using&nbsp;code&nbsp;contracts:[ContractInvariantMethod]protected&nbsp;void&nbsp;ObjectInvariant&nbsp;()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Contract.Invariant&nbsp;(&nbsp;X&nbsp;!=&nbsp;null&nbsp;); &nbsp;&nbsp;&nbsp;&nbsp;//...}出于这个原因,.NET应用程序存在Code Contracts项目。或者,可以使用断言来应用合同设计。更新:值得一提的是,这个术语是Bertrand Meyer&nbsp;在设计Eiffel编程语言时创造的。
打开App,查看更多内容
随时随地看视频慕课网APP