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

对象引用未设置为对象的实例。

这意味着什么,我可以做什么来修复这个错误?


当前回答

关于“我该怎么办”的问题,可以有很多答案。

在开发时防止这种错误情况的一种更“正式”的方法是在代码中应用契约设计。这意味着在开发时,需要在系统上设置类不变量,和/或甚至函数/方法前置条件和后置条件。

简而言之,类不变量确保类中有一些约束在正常使用中不会被违反(因此,类不会处于不一致的状态)。前置条件意味着作为函数/方法输入的数据必须遵循某些约束集,并且永远不会违反这些约束,后置条件意味着函数/方法输出必须再次遵循这些约束集,而永远不会违反它们。在执行无错误程序期间,不应违反合同条件,因此,在调试模式下实际检查合同设计,而在发布版本中禁用,以最大化开发的系统性能。

通过这种方式,可以避免由于违反约束集而导致的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应用程序存在代码合同项目。

或者,可以使用断言应用契约设计。

更新:值得一提的是,这个词是Bertrand Meyer在设计Eiffel编程语言时创造的。

其他回答

当我们试图访问空对象的财产时,或者当字符串值变为空并且我们试图访问字符串方法时,会抛出NullReferenceException。

例如:

访问空字符串的字符串方法时:string str=string.Empty;str.ToLower();//抛出空引用异常访问空对象的属性时:公共类人员{公共字符串名称{get;set;}}人员对象人员;objPerson.Name///抛出空引用异常

这意味着您的代码使用了一个设置为null的对象引用变量(即它没有引用实际的对象实例)。

为了防止出现错误,应该在使用可能为空的对象之前测试其是否为空。

if (myvar != null)
{
    // Go ahead and use myvar
    myvar.property = ...
}
else
{
    // Whoops! myvar is null and cannot be used without first
    // assigning it to an instance reference
    // Attempting to use myvar here will result in NullReferenceException
}

TL;DR:尝试使用Html.Parate而不是Renderpage


当我试图通过发送模型在视图中呈现视图时,我得到的对象引用未设置为对象的实例,如下所示:

@{
    MyEntity M = new MyEntity();
}
@RenderPage("_MyOtherView.cshtml", M); // error in _MyOtherView, the Model was Null

调试显示模型在MyOtherView中为Null。直到我将其更改为:

@{
    MyEntity M = new MyEntity();
}
@Html.Partial("_MyOtherView.cshtml", M);

它奏效了。

此外,我没有Html.Paraal的原因是,Visual Studio有时会在Html.Partial下抛出看起来像错误的曲线,如果它位于不同构造的foreach循环中,即使它不是真正的错误:

@inherits System.Web.Mvc.WebViewPage
@{
    ViewBag.Title = "Entity Index";
    List<MyEntity> MyEntities = new List<MyEntity>();
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
}
<div>
    @{
        foreach(var M in MyEntities)
        {
            // Squiggly lines below. Hovering says: cannot convert method group 'partial' to non-delegate type Object, did you intend to envoke the Method?
            @Html.Partial("MyOtherView.cshtml");
        }
    }
</div>

但我能够运行应用程序,没有出现任何问题。通过将foreach循环的结构更改为如下所示,我能够消除该错误:

@foreach(var M in MyEntities){
    ...
}

虽然我觉得这是因为Visual Studio误读了符号和括号。

这意味着所讨论的变量没有指向任何对象。我可以这样生成:

SqlConnection connection = null;
connection.Open();

这将引发错误,因为虽然我声明了变量“connection”,但它没有指向任何对象。当我尝试将成员称为“Open”时,没有任何引用可供它解析,它会抛出错误。

要避免此错误,请执行以下操作:

在尝试对对象执行任何操作之前,请始终初始化对象。如果您不确定对象是否为空,请使用object==null进行检查。

JetBrains的ReSharper工具将识别代码中可能出现空引用错误的每个位置,从而允许您进行空检查。这个错误是错误的头号来源,IMHO。

错误行“Object reference not set to an instance of a Object.”表示您尚未将实例对象分配给对象引用,但仍在访问该对象的财产/方法。

例如:假设您有一个名为myClass的类,它包含一个属性prop1。

public Class myClass
{
   public int prop1 {get;set;}
}

现在,您正在访问其他类中的prop1,如下所示:

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref.prop1 = 1;  // This line throws an error
     }
}

上述行引发错误,因为类myClass的引用已声明,但未实例化,或者对象的实例未分配给该类的引用。

要解决这个问题,必须实例化(将对象分配给该类的引用)。

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref = new myClass();
        ref.prop1 = 1;
     }
}