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

时间:2011-01-11 16:48:29

标签: c# .net vb.net null nullreferenceexception

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

  

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

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

30 个答案:

答案 0 :(得分:2266)

答案 1 :(得分:223)

另一种情况是将空对象强制转换为value type。例如,下面的代码:

object o = null;
DateTime d = (DateTime)o;

它会在演员表上抛出NullReferenceException。在上面的示例中似乎很明显,但这可能发生在更多“后期绑定”复杂场景中,其中null对象已从您不拥有的某些代码返回,并且转换例如由某个自动系统生成。

这个例子就是这个带有Calendar控件的简单ASP.NET绑定片段:

<asp:Calendar runat="server" SelectedDate="<%#Bind("Something")%>" />

在这里,SelectedDate实际上是DateTime类型的属性 - Calendar Web控件类型,并且绑定可以完美地返回null。隐式ASP.NET生成器将创建一段代码,它将等同于上面的强制转换代码。这会引发一个很难发现的NullReferenceException,因为它位于ASP.NET生成的代码中,编译得很好......

答案 2 :(得分:155)

这意味着有问题的变量无效。我可以这样生成:

SqlConnection connection = null;
connection.Open();

这将抛出错误,因为当我声明变量“connection”时,它没有指向任何东西。当我尝试调用成员“Open”时,没有引用它来解决它,它会抛出错误。

为避免此错误:

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

    JetBrains的Resharper工具将识别代码中可能存在空引用错误的每个位置,允许您进行空检查。这个错误是错误的头号来源,恕我直言。

答案 3 :(得分:151)

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

为防止出现错误,可以在使用之前测试null为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
}

答案 4 :(得分:94)

请注意,无论情况如何,.NET中的原因始终相同:

  

您正在尝试使用值为Nothing / null的引用变量。当引用变量的值为Nothing / null时,这意味着它实际上并未持有对堆上存在的任何对象的实例的引用。

     

您从未向变量分配过某些东西,从未创建过分配给变量的值的实例,或者您手动将变量设置为Nothing / null,或者您调用的函数是将变量设置为Nothing / null

答案 5 :(得分:85)

抛出此异常的一个示例是:当您尝试检查某些内容时,该值为null。

例如:

string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)

if (testString.Length == 0) // Throws a nullreferenceexception
{
    //Do something
} 

当您尝试对尚未实例化的内容(即上面的代码)执行操作时,.NET运行时将抛出NullReferenceException。

与ArgumentNullException相比,如果方法期望传递给它的内容不为null,则通常将其作为防御措施抛出。

更多信息位于 C# NullReferenceException and Null Parameter

答案 6 :(得分:81)

如果您尚未初始化引用类型,并且想要设置或读取其中一个属性,则会抛出 NullReferenceException

示例:

Person p = null;
p.Name = "Harry"; // NullReferenceException occurs here.

您可以通过检查变量是否为空来简单地避免这种情况:

Person p = null;
if (p!=null)
{
    p.Name = "Harry"; // Not going to run to this point
}

要完全理解为什么抛出NullReferenceException,了解value typesreference types之间的区别非常重要。

因此,如果您正在处理值类型,则NullReferenceExceptions可以。虽然在处理引用类型时需要保持警惕!

正如名称所暗示的,只有引用类型可以保存引用或从字面上指向任何内容(或“null”)。值类型始终包含值。

参考类型(必须检查这些类型):

  • 动态
  • 物体
  • 字符串

值类型(您可以忽略这些类型):

  • 数字类型
  • 积分类型
  • 浮点类型
  • 小数
  • BOOL
  • 用户定义的结构

答案 7 :(得分:75)

NullReferenceExceptions可能发生的另一种情况是({3}}使用(错误):

class Book {
    public string Name { get; set; }
}
class Car { }

Car mycar = new Car();
Book mybook = mycar as Book;   // Incompatible conversion --> mybook = null

Console.WriteLine(mybook.Name);   // NullReferenceException

此处,BookCar是不兼容的类型; Car无法转换/转换为Book。当此演员失败时,as会返回null。在此之后使用mybook会导致NullReferenceException

通常,您应该使用演员表或as,如下所示:

如果您希望类型转换始终成功(即您知道对象应该提前做什么),那么您应该使用强制转换:

ComicBook cb = (ComicBook)specificBook;

如果您不确定类型,但想要尝试将其用作特定类型,请使用as

ComicBook cb = specificBook as ComicBook;
if (cb != null) {
   // ...
}

答案 8 :(得分:63)

您正在使用包含空值引用的对象。所以它给出了一个null异常。在示例中,字符串值为null,并且在检查其长度时,发生了异常。

示例:

string value = null;
if (value.Length == 0) // <-- Causes exception
{
    Console.WriteLine(value); // <-- Never reached
}

异常错误是:

  

未处理的例外:

     

System.NullReferenceException:未将对象引用设置为实例   一个对象。在Program.Main()

答案 9 :(得分:60)

虽然 导致NullReferenceExceptions避免/修复的方法已经在其他答案中解决了这样的异常,但许多程序员还没有学到什么是如何在开发过程中独立调试这样的异常。

在Visual Studio中,由于Visual Studio Debugger,这通常很容易。


首先,确保将捕获正确的错误 - 请参阅 How do I allow breaking on 'System.NullReferenceException' in VS2010? 注意 1

然后是Start with Debugging (F5)Attach [the VS Debugger] to Running Process。有时使用Debugger.Break可能会有用,它会提示启动调试器。

现在,当抛出(或未处理)NullReferenceException时,调试器将在发生异常的行上停止(记住上面的规则集?)。有时错误很容易发现。

例如, 在以下行中,可以导致异常的唯一代码是myString计算为null。这可以通过查看Watch Window中的Immediate Window或正在运行的表达式来验证。

var x = myString.Trim();

在更高级的情况下,例如以下情况,您需要使用上述技术之一(Watch或Immediate Windows)来检查表达式,以确定str1是否为null或{{1} }是空的。

str2

一旦其中抛出了异常,通常会向后推理以找出[错误地]引入空值的位置 -

花些时间了解异常原因。检查空表达式。检查可能导致此类空表达式的先前表达式。添加breakpoints并根据需要逐步执行该程序。 使用调试器。


1 如果Break of Throws过于激进并且调试器在.NET或第三方库中的NPE上停止,Break on User-Unhandled可用于限制捕获的异常。此外,VS2012还引入了Just My Code我建议也启用。

  

如果您正在使用“启用我的代码”进行调试,则行为会略有不同。启用“仅我的代码”后,调试器将忽略在“我的代码”之外抛出并且不通过“我的代码”的第一次机会公共语言运行时(CLR)异常

答案 10 :(得分:55)

Simon Mourier gave this example

object o = null;
DateTime d = (DateTime)o;  // NullReferenceException

来自 object(或来自其中一个类System.ValueType 拆箱 转换(强制转换) System.Enum,或来自界面类型)值类型(Nullable<>除外)本身会提供NullReferenceException

另一方面,来自 Nullable<> 拳击 转换 HasValue等于{{ 1}} 引用类型,可以提供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. 实例时使用的特殊规则。

答案 11 :(得分:40)

在实体框架中使用的实体的类名与Web表单代码隐藏文件的类名相同时添加一个案例。

假设您有一个Web表单Contact.aspx,其代码隐藏类是Contact,并且您有一个实体名称Contact。

然后,当您调用context.SaveChanges()

时,以下代码将抛出NullReferenceException
Contact contact = new Contact { Name = "Abhinav"};
var context = new DataContext();
context.Contacts.Add(contact);
context.SaveChanges(); // NullReferenceException at this line

为了完整性DataContext类

public class DataContext : DbContext 
{
    public DbSet<Contact> Contacts {get; set;}
}

和联系实体类。有时实体类是部分类,因此您也可以在其他文件中扩展它们。

public partial class Contact 
{
    public string Name {get; set;}
}

当实体和代码隐藏类都在同一名称空间中时,会发生错误。 要解决此问题,请为Contact.aspx重命名实体类或代码隐藏类。

<强>原因 我仍然不确定原因。但只要任何实体类都会扩展System.Web.UI.Page,就会发生此错误。

有关讨论,请查看NullReferenceException in DbContext.saveChanges()

答案 12 :(得分:39)

另一个可能会收到此异常的一般情况涉及在单元测试期间模拟类。无论使用何种模拟框架,都必须确保正确模拟类层次结构的所有适当级别。特别是,必须模拟被测试代码引用的HttpContext的所有属性。

有关详细的示例,请参阅“NullReferenceException thrown when testing custom AuthorizationAttribute”。

答案 13 :(得分:38)

我对回答这个问题有不同的看法。这种答案“我还能做些什么来避免它?

在不同层中工作时,例如在MVC应用程序中,控制器需要服务来调用业务操作。在这种情况下,依赖注入容器可用于初始化服务以避免 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();
    }
}

答案 14 :(得分:37)

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

在开发时,一种更“正式”的方法可以防止 在您的代码中应用 design by contract 。这意味着您需要在开发时在系统上设置类不变量,和/或甚至函数/方法前提条件后置条件

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

这样,您可以避免违反约束集的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 项目。

或者,可以使用 assertions 来应用合同设计。

更新:值得一提的是,这个词是由Bertrand Meyer in connection with his design of the Eiffel programming language创造的。

答案 15 :(得分:34)

当我们尝试访问null对象的Properties或者字符串值变为空并且我们尝试访问字符串方法时,抛出NullReferenceException

例如:

  1. 访问空字符串的字符串方法时:

    string str = string.Empty;
    str.ToLower(); // throw null reference exception
    
  2. 访问空对象的属性时:

    Public Class Person {
        public string Name { get; set; }
    }
    Person objPerson;
    objPerson.Name  /// throw Null refernce Exception 
    

答案 16 :(得分:30)

TL; DR :尝试使用Html.Partial代替Renderpage

当我尝试通过向视图中发送一个模型来渲染视图时,我得到Object reference not set to an instance of an object,如下所示:

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

调试显示模型在MyOtherView中是空的。直到我把它改为:

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

它有效。

此外,我没有开始Html.Partial的原因是因为Visual Studio 有时会在Html.Partial下抛出看起来错误的波浪线,如果它&#39 ; s在一个不同构造的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>

但是我能够运行应用程序而没有出现此问题&#34;错误&#34;。我能够通过改变foreach循环的结构来消除错误,如下所示:

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

虽然我有一种感觉,因为Visual Studio误读了&符号和括号。

答案 17 :(得分:22)

你能做些什么?

这里有很多很好的答案,解释了什么是空引用以及如何调试它。但是如何防止这个问题或者至少让它更容易被捕获的问题很少。

检查参数

例如,方法可以检查不同的参数以查看它们是否为空并抛出ArgumentNullException,这是一个明显为此目的而创建的异常。

ArgumentNullException的构造函数甚至将参数的名称和消息作为参数,这样您就可以准确地告诉开发人员问题是什么。

public void DoSomething(MyObject obj) {
    if(obj == null) 
    {
        throw new ArgumentNullException("obj", "Need a reference to obj.");
    }
}

使用工具

还有几个图书馆可以提供帮助。 &#34; ReSharper的&#34;例如,在编写代码时可以为您提供警告,尤其是在您使用其属性时:NotNullAttribute

有&#34; Microsoft Code Contracts&#34;您使用Contract.Requires(obj != null)之类的语法,它为您提供运行时和编译检查:Introducing Code Contracts

还有&#34; PostSharp&#34;这将允许您只使用这样的属性:

public void DoSometing([NotNull] obj)

通过这样做,并使构建过程obj的PostSharp部分在运行时检查为null。请参阅:PostSharp null check

普通代码解决方案

或者您始终可以使用普通旧代码编写自己的方法。例如,这是一个可用于捕获空引用的结构。它的构建方式与Nullable<T>

相同
[System.Diagnostics.DebuggerNonUserCode]
public struct NotNull<T> where T: class
{
    private T _value;

    public T Value
    {
        get
        {
            if (_value == null)
            {
                throw new Exception("null value not allowed");
            }

            return _value;
        }
        set
        {
            if (value == null)
            {
                throw new Exception("null value not allowed.");
            }

            _value = value;
        }
    }

    public static implicit operator T(NotNull<T> notNullValue)
    {
        return notNullValue.Value;
    }

    public static implicit operator NotNull<T>(T value)
    {
        return new NotNull<T> { Value = value };
    }
}

您将使用与使用Nullable<T>相同的方式,但目标是完全相反 - 不允许null。以下是一些例子:

NotNull<Person> person = null; // throws exception
NotNull<Person> person = new Person(); // OK
NotNull<Person> person = GetPerson(); // throws exception if GetPerson() returns null

NotNull<T>隐式强制转换为T,因此您可以在任何需要的地方使用它。例如,您可以将Person对象传递给采用NotNull<Person>

的方法
Person person = new Person { Name = "John" };
WriteName(person);

public static void WriteName(NotNull<Person> person)
{
    Console.WriteLine(person.Value.Name);
}

正如您在上面看到的那样,您可以通过Value属性访问基础值。或者,您可以使用显式或隐式强制转换,您可以看到一个带有以下返回值的示例:

Person person = GetPerson();

public static NotNull<Person> GetPerson()
{
    return new Person { Name = "John" };
}

或者,当方法通过执行强制转换返回T(在本例中为Person)时,您甚至可以使用它。例如,以下代码就像上面的代码一样:

Person person = (NotNull<Person>)GetPerson();

public static Person GetPerson()
{
    return new Person { Name = "John" };
}

与分机结合

NotNull<T>与扩展方法结合使用,您可以涵盖更多情况。以下是扩展方法的示例:

[System.Diagnostics.DebuggerNonUserCode]
public static class NotNullExtension
{
    public static T NotNull<T>(this T @this) where T: class
    {
        if (@this == null)
        {
            throw new Exception("null value not allowed");
        }

        return @this;
    }
}

这是一个如何使用它的例子:

var person = GetPerson().NotNull();

GitHub的

为了您的参考,我在GitHub上提供了上面的代码,您可以在以下网址找到它:

https://github.com/luisperezphd/NotNull

相关语言功能

C#6.0引入了&#34; null-conditional运算符&#34;这有点帮助。使用此功能,您可以引用嵌套对象,如果其中任何一个为null,则整个表达式将返回null

这减少了在某些情况下您必须执行的空检查的数量。语法是在每个点之前加上一个问号。以下面的代码为例:

var address = country?.State?.County?.City;

想象一下,countryCountry类型的对象,它具有一个名为State的属性,依此类推。如果countryStateCountyCitynull,则address will be null . Therefore you only have to check whether地址is null `。

这是一个很棒的功能,但它可以为您提供更少的信息。它并没有明确表明4中的哪一个是空的。

内置如Nullable?

C#对Nullable<T>有一个很好的简写,你可以通过在类型int?之后加一个问号来使某些东西可以为空。

如果C#上面有NotNull<T>结构,并且有类似的简写,可能是感叹号(!),那么你可以编写类似于:public void WriteName(Person! person)的内容。

答案 18 :(得分:9)

您可以使用c#6中的Null条件运算符以干净的方式修复NullReferenceException,并编写更少的代码来处理空值检查。

在执行成员访问(?。)或索引(?[)操作之前,它曾用于测试null。

实施例

  var name = p?.Spouse?.FirstName;

相当于:

    if (p != null)
    {
        if (p.Spouse != null)
        {
            name = p.Spouse.FirstName;
        }
    }

结果是当p为null或p.Spouse为null时,名称将为null。

否则,将为变量名称分配p.Spouse.FirstName的值。

详细信息:Null-conditional Operators

答案 19 :(得分:8)

错误行“对象引用未设置为对象的实例。 “声明您尚未将实例对象分配给对象引用,并且您仍在访问该对象的属性/方法。

例如:假设您有一个名为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 error
     }
}

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

要修复此问题,您必须实例化(将对象分配给该类的引用)。

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

答案 20 :(得分:8)

有趣的是,这个页面上没有一个答案提到了两个边缘情况,希望没有人介意我添加它们:

边缘情况#1:并发访问字典

.NET中的通用字典不是线程安全的,当您尝试访问密钥时,它们有时可能会抛出>>> sentence1 = 'the quick brown fox jumped over the lazy dog' >>> sentence2 = 'the quck brown fox jumped!1 over the lazy! dog!!!' >>> all(c.isalpha() or c.isspace() for c in sentence1) True >>> all(c.isalpha() or c.isspace() for c in sentence2) False >>> 甚至(更频繁)NullReference来自两个并发线程。在这种情况下,例外是非常误导的。

边缘情况#2:不安全代码

如果KeyNotFoundException代码抛出NullReferenceException,您可能会查看指针变量,并检查unsafe或其他内容。这是同样的事情(“空指针异常”),但在不安全的代码中,变量通常被强制转换为值类型/数组等,并且你会撞到墙上,想知道值类型如何抛出这个例外。

(顺便说一下,除非你需要,否则不使用不安全代码的另一个原因)

答案 21 :(得分:3)

当您尝试使用的类的对象未实例化时,会发生未设置为对象实例的NullReferenceException或Object引用。 例如:

假设您有一个名为Student的课程。

public class Student
{
    private string FirstName;
    private string LastName;
    public string GetFullName()
    {
        return FirstName + LastName;
    }
}

现在,考虑另一个你试图检索学生全名的课程。

public class StudentInfo
{      
    public string GetStudentName()
    {
        Student s;
        string fullname = s.GetFullName();
        return fullname;
    }        
}

如上面的代码所示,声明 学生 - 仅声明Student类型的变量,请注意此时未实例化Student类。 因此,当语句 s.GetFullName()被执行时,它将抛出NullReferenceException。

答案 22 :(得分:2)

嗯,简单来说:

您正在尝试访问未创建或当前不在内存中的对象。

那么如何解决这个问题:

  1. 调试并让调试器中断...它将直接将您带到已损坏的变量...现在您的任务是简单地修复此问题。使用 new 关键字在适当的地方。

  2. 如果它是由某个数据库命令引起的,因为该对象不存在,那么您需要做的就是进行空检查并处理它:

    if (i == null) {
        // Handle this
    }
    
  3. 最难的......如果 GC 已经收集了对象...如果你试图使用字符串找到一个对象,通常会发生这种情况...这是通过对象的名称找到它然后可能会发生GC可能已经清理它......这很难找到并且将成为一个很大的问题...解决这个问题的一个更好的方法是在必要时进行空检查发展过程。这将为您节省大量时间。

  4. 通过名称查找我的意思是一些框架允许您使用字符串来使用FIndObjects,代码可能如下所示: FindObject(“ObjectName”);

答案 23 :(得分:0)

如果我们考虑可以抛出此异常的常见场景,请访问顶部带有对象的属性。

前:

string postalcode=Customer.Address.PostalCode; 
//if customer or address is null , this will through exeption

在这里,如果address为null,那么你将获得NullReferenceException。

因此,在访问此类对象中的属性(特别是通用)之前,我们应该始终使用null检查

string postalcode=Customer?.Address?.PostalCode;
//if customer or address is null , this will return null, without through a exception

答案 24 :(得分:0)

从字面上看,修复NullReferenceExeption最简单的方法有两种。 如果您有一个附加脚本的GameObject和一个名为rb(rigidbody)的变量,那么当您开始游戏时,此变量将从null开始。
这就是您获得NullReferenceExeption的原因,因为计算机没有存储在该变量中的数据。

我将使用RigidBody变量作为示例 我们可以通过以下几种方式实际添加数据:

  1. 使用AddComponent&gt;为您的对象添加RigidBody物理学&gt;刚体
    然后进入您的脚本并输入rb = GetComponent<Rigidbody>();
    这行代码最适合您的Start()Awake()函数。
  2. 您可以通过编程方式添加组件,并使用一行代码同时分配变量:rb = AddComponent<RigidBody>();
  3. 进一步说明:如果你想让Unity为你的对象添加一个组件而你可能忘记添加一个组件,你可以在你的类声明上方输入[RequireComponent(typeof(RigidBody))](所有使用中的空间)。 /> 享受并享受制作游戏的乐趣!

答案 25 :(得分:-1)

如果在保存或编译构建期间收到此消息,只需关闭所有文件,然后打开任何文件进行编译和保存。

对我来说,原因是我重命名了文件,旧文件仍然打开。

答案 26 :(得分:-1)

要使用对象的方法和成员,首先必须创建该对象。如果你没有创建它(应该保持对象的变量没有被初始化),但是你尝试使用它的方法或变量,你会得到那个错误。

有时你可能忘了做初始化。

已编辑: new无法返回null,但在失败时会触发异常。很久以前,某些语言就是这种情况,但现在已经不是了。谢谢@John Saunders指出这一点。

答案 27 :(得分:-2)

这基本上是一个空引用异常。正如Microsoft所述 -

  

尝试访问时抛出NullReferenceException异常   值为null的类型的成员。

这是什么意思?

这意味着如果任何没有任何价值且我们让该成员执行某项任务的成员,那么系统无疑会抛出一条消息并说 -

“嘿等等,该成员没有值,因此无法执行您将其交给的任务。”

异常本身表示正在引用某些内容但其值未设置。所以这表示它只在使用引用类型时发生,因为值类型是不可为空的。

如果我们使用Value类型成员,则不会发生NullReferenceException。

class Program
{
    static void Main(string[] args)
    {
        string str = null;
        Console.WriteLine(str.Length);
        Console.ReadLine();
    }
}

上面的代码显示了一个简单的字符串,该字符串分配了 null 值。

现在,当我尝试打印字符串 str 的长度时,我得到一个未处理的类型'System.NullReferenceException'发生消息的异常,因为成员 str 指向null,并且不能有任何null的长度。

当我们忘记实例化引用类型时,也会发生

' NullReferenceException '。

假设我有一个类和成员方法。我没有实例化我的课程,只是命名我的班级。现在,如果我尝试使用该方法,编译器将抛出错误或发出警告(取决于编译器)。

class Program
{
    static void Main(string[] args)
    {
        MyClass1 obj;
        obj.foo();  //Use of unassigned local variable 'obj'
    }
}

public class MyClass1
{
    internal void foo()
    {
        Console.WriteLine("hello from foo");

    }
}

上面代码的编译器引发了一个错误,即变量 obj 未被赋值,这表示我们的变量具有空值或什么都没有。上面代码的编译器引发了一个错误,即变量 obj 未被赋值,这表示我们的变量具有空值或什么都没有。

为什么会发生?

  • 由于我们没有检查对象值的错误而出现NullReferenceException。我们经常在代码开发中保留未选中的对象值。

  • 当我们忘记实例化对象时也会出现这种情况。使用可返回或设置空值的方法,属性,集合等也可能是导致此异常的原因。

如何避免?

有许多方法和方法可以避免这个着名的例外:

  1. 显式检查:我们应该遵循检查对象,属性,方法,数组和集合的传统,无论它们是否为空。这可以使用if-else if-else等条件语句简单地实现。

  2. 异常处理:管理此异常的重要方法之一。使用简单的try-catch-finally块,我们可以控制此异常并维护它的日志。当您的应用程序处于生产阶段时,这非常有用。

  3. Null运算符:Null Coalescing运算符和空条件运算符也可以在将值设置为对象,变量,属性和字段时使用。

  4. 调试器:对于开发人员,我们拥有调试的重要武器。如果我们在开发面部遇到NullReferenceException,我们可以使用调试器来获取异常的来源。

  5. 内置方法:系统方法(如GetValueOrDefault(),IsNullOrWhiteSpace()和IsNullorEmpty()检查空值,如果存在空值,则指定默认值。

  6. 这里有很多好的答案。您还可以使用我的blog上的示例查看更详细的说明。

    希望这也有帮助!

答案 28 :(得分:-5)

有一种情况可能发生 Class 相关。在我陈述决议之前,这个问题最终被关闭了: https://stackoverflow.com/questions/43348009/unable-to-instantiate-class

注意没有实例化的类:如果类中构造函数的任何部分抛出null reference exception,则该类不会实例化。在我的情况下,它试图从web.config获取一个不存在的连接字符串。

我实例化了一个类:

ClassName myClass = new ClassName();
myClass.RunSomeMethod();

在类本身内部是调用从web.config获取连接字符串。构造函数的这一部分抛出了一个空值异常,因此myClass为空。

如果您遇到过没有实例化的类的情况,请尝试确保类构造函数的任何部分都不会抛出null value exception。 F-11并逐步完成课程并确保没有空值。

答案 29 :(得分:-5)

  

您正在尝试访问未创建或当前未在内存中的对象。

当我收到此错误时,我将以下代码添加到任何触发错误的事件处理程序。

if (!IsLoaded) return;

!意思是&#34;不是&#34;,仅供参考。因此,如果没有加载有问题的对象,程序将终止执行并防止崩溃。