15 回答
TA贡献1821条经验 获得超4个赞
这意味着有问题的变量没有任何意义。我可以这样生成:
SqlConnection connection = null;connection.Open();
这将抛出错误,因为当我声明变量“ connection
”时,它没有指向任何东西。当我尝试调用成员“ Open
”时,没有引用它来解决它,它将抛出错误。
要避免此错误:
在尝试对它们执行任何操作之前始终初始化对象。
如果您不确定对象是否为null,请检查它
object == null
。
JetBrains的Resharper工具将识别代码中可能存在空引用错误的每个位置,允许您进行空检查。这个错误是错误的头号来源,恕我直言。
TA贡献1824条经验 获得超8个赞
请注意,无论情况如何,.NET中的原因始终相同:
您正在尝试使用值为
Nothing
/ 的引用变量null
。当值为Nothing
/null
为引用变量时,这意味着它实际上并未持有对堆上存在的任何对象的实例的引用。您从未向变量分配内容,从未创建分配给变量的值的实例,或者您将变量设置为
Nothing
/null
manual,或者您调用了将变量设置为Nothing
/ 的函数null
。
TA贡献1851条经验 获得超4个赞
您正在使用包含空值引用的对象。所以它给出了一个null异常。在示例中,字符串值为null,并且在检查其长度时,发生了异常。
例:
string value = null;if (value.Length == 0) // <-- Causes exception{ Console.WriteLine(value); // <-- Never reached}
异常错误是:
未处理的异常:
System.NullReferenceException:未将对象引用设置为对象的实例。在Program.Main()
TA贡献1815条经验 获得超10个赞
object o = null;DateTime d = (DateTime)o; // NullReferenceException
其中一个开箱转换(CAST)从 object
(或从其中一个类System.ValueType
或System.Enum
,或从一个接口类型)到一个值类型(比其它Nullable<>
本身)给出NullReferenceException
。
在另一个方向上,一拳击转换从一个Nullable<>
具有HasValue
等于false
以引用类型,可以给一个null
参考其然后可以在以后导致NullReferenceException
。经典的例子是:
DateTime? d = null;var s = d.ToString(); // OK, no exception (no boxing), returns ""var t = d.GetType(); // Bang! d is boxed, NullReferenceException
有时拳击以另一种方式发生。例如,使用这种非泛型扩展方法:
public static void MyExtension(this object x){ x.ToString();}
以下代码将有问题:
DateTime? d = null;d.MyExtension(); // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.
出现这些情况是因为运行时在装箱Nullable<>
实例时使用的特殊规则。
TA贡献1803条经验 获得超6个赞
我对回答这个问题有不同的看法。这种答案“我还能做些什么来避免它? ”
当跨不同层工作时,例如在MVC应用程序中,控制器需要服务来调用业务操作。在这种情况下,可以使用Dependency Injection Container初始化服务以避免NullReferenceException。这意味着您不必担心检查null并且只需从控制器调用服务,就好像它们总是可用(并初始化)为单例或原型。
public class MyController{ private ServiceA serviceA; private ServiceB serviceB; public MyController(ServiceA serviceA, ServiceB serviceB) { this.serviceA = serviceA; this.serviceB = serviceB; } public void MyMethod() { // We don't need to check null because the dependency injection container // injects it, provided you took care of bootstrapping it. var someObject = serviceA.DoThis(); }}
TA贡献1836条经验 获得超3个赞
关于“我该怎么办”,可以有很多答案。
在开发过程中防止此类错误情况的更“正式”方法是在代码中按合同设计。这意味着您需要在开发时在系统上设置类不变量,和/或甚至函数/方法前置条件和后置条件。
简而言之,类不变量确保您的类中存在一些在正常使用中不会被违反的约束(因此,类不会处于不一致状态)。前提条件意味着作为函数/方法的输入给出的数据必须遵循一些约束集并且永远不违反它们,并且后置条件意味着函数/方法输出必须再次遵循设置约束而不违反它们。在执行无错误程序期间永远不应违反合同条件,因此在调试模式下实际检查合同设计,同时在发布中禁用合同条件,以最大化已开发的系统性能。
这样,您可以避免NullReferenceException
违反约束集的情况。例如,如果X
在类中使用对象属性,稍后尝试调用其中一个方法并且X
具有空值,则会导致NullReferenceException
:
public X { get; set; }public void InvokeX(){ X.DoSomething(); // if X value is null, you will get a NullReferenceException}
但是如果你设置“属性X必须永远不会有空值”作为方法前置条件,那么你可以阻止前面描述的场景:
//Using code contracts:[ContractInvariantMethod]protected void ObjectInvariant () { Contract.Invariant ( X != null ); //...}
出于这个原因,.NET应用程序存在Code Contracts项目。
或者,可以使用断言来应用合同设计。
更新:值得一提的是,这个术语是Bertrand Meyer 在设计Eiffel编程语言时创造的。
- 15 回答
- 0 关注
- 9812 浏览
添加回答
举报