C# 什么是NullReferenceException,如何修复它?

C# 什么是NullReferenceException,如何修复它?,c#,.net,vb.net,null,nullreferenceexception,C#,.net,Vb.net,Null,Nullreferenceexception,我有一些代码,当它执行时,它抛出一个NullReferenceException,说: 对象引用未设置为对象的实例 这意味着什么?我能做些什么来修复此错误?这意味着您的代码使用了一个设置为null的对象引用变量(即,它没有引用实际的对象实例) 为了防止出现错误,应该在使用可能为null的对象之前对其进行null测试 if (myvar != null) { // Go ahead and use myvar myvar.property = ... } else { //

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

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


这意味着什么?我能做些什么来修复此错误?

这意味着您的代码使用了一个设置为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
}

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

SqlConnection connection = null;
connection.Open();
这将抛出错误,因为虽然我声明了变量“
connection
”,但它没有指向任何东西。当我尝试调用成员“
Open
”时,没有要解决的引用,它将抛出错误

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

  • 在尝试对对象执行任何操作之前,请始终初始化对象
  • 如果不确定对象是否为空,请使用
    object==null
    检查它
  • JetBrains的工具将识别代码中可能出现空引用错误的每个地方,允许您进行空检查。这个错误是bug的头号来源,IMHO。

    原因是什么? 底线 您试图使用的是
    null
    (或VB.NET中的
    Nothing
    )。这意味着您要么将其设置为
    null
    ,要么根本不将其设置为任何值

    像其他任何东西一样,
    null
    被传递。如果方法“A”中的
    null
    ,则可能是方法“B”将A
    null
    传递给了方法“A”

    null
    可以有不同的含义:

  • 未初始化的对象变量,因此不指向任何对象。在这种情况下,如果访问此类对象的成员,则会导致
    NullReferenceException
  • 开发人员有意使用
    null
    来表示没有可用的有意义的值。请注意,C#有变量的可空数据类型的概念(就像数据库表可以有可空字段)-您可以将
    null
    分配给它们,以表示其中没有存储值,例如
    int?a=零
    (这是
    可空a=null;
    的快捷方式),其中问号表示允许将
    null
    存储在变量
    a
    中。您可以使用
    if(a.HasValue){…}
    if(a==null){…}
    检查这一点。可为空的变量,如本例中的
    a
    ,允许通过
    a.value
    显式访问值,或通过
    a
    正常访问值
    注意如果
    a
    null
    ,则通过
    a.Value
    访问它会引发
    InvalidOperationException
    而不是
    NullReferenceException
    ——您应该事先进行检查,即如果您有另一个不可为null的变量
    int b
    然后您应该执行类似于
    if(a.HasValue){b=a.Value;}
    或更短的
    if(a!=null){b=a;}
  • 本文的其余部分将更详细地介绍许多程序员经常犯的错误,这些错误可能导致
    NullReferenceException

    更具体地说
    运行时
    抛出
    NullReferenceException
    始终表示相同的意思:您正在尝试使用引用,但引用未初始化(或者它已初始化,但不再初始化)

    这意味着引用是
    null
    ,您不能通过
    null
    引用访问成员(例如方法)。最简单的情况是:

    字符串foo=null;
    foo.ToUpper();
    
    这将在第二行抛出一个
    NullReferenceException
    ,因为您无法对指向
    null
    字符串
    引用调用实例方法
    ToUpper()

    调试 如何查找
    NullReferenceException
    的源?除了查看异常本身(将在异常发生的位置准确抛出)之外,Visual Studio中调试的一般规则也适用:放置战略性断点,或者将鼠标悬停在断点的名称上,打开(快速)监视窗口,或者使用各种调试面板(如局部变量和自动变量)

    如果要查找引用的设置位置或未设置位置,请右键单击其名称并选择“查找所有引用”。然后,您可以在找到的每个位置放置一个断点,并在附加调试程序的情况下运行程序。每次调试器在这样一个断点上中断时,您都需要确定是否期望引用为非null,检查变量,并验证它是否在期望时指向实例

    通过以这种方式遵循程序流,您可以找到实例不应为null的位置以及未正确设置的原因

    例子 可以引发异常的一些常见场景:

    通用的
    ref1.ref2.ref3.member
    
    如果ref1、ref2或ref3为null,则会得到一个
    NullReferenceException
    。如果要解决此问题,请将表达式重写为更简单的等价表达式,以确定哪一个为空:

    var r1=ref1;
    var r2=r1.ref2;
    var r3=r2.ref3;
    r3.成员
    
    具体来说,在
    HttpContext.Current.User.Identity.Name
    中,
    HttpContext.Current
    可以为null,或者
    User
    属性可以为null,或者
    Identity
    属性可以为null

    间接的
    公共类人物
    {
    公共整数{get;set;}
    }
    公共课堂用书
    {
    公共人物作者{get;set;}
    }
    公开课范例
    {
    公共图书馆
    {
    书b1=新书();
    int authorAge=b1.Author.Age;//您从未初始化Author属性。
    
    Person[] people = new Person[5];
    people[0].Age = 20 // people[0] is null. The array was allocated but not
                       // initialized. There is no Person to set the Age for.
    
    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
    } 
    
    object o = null;
    DateTime d = (DateTime)o;
    
    <asp:Calendar runat="server" SelectedDate="<%#Bind("Something")%>" />
    
    string value = null;
    if (value.Length == 0) // <-- Causes exception
    {
        Console.WriteLine(value); // <-- Never reached
    }
    
    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
    
    ComicBook cb = (ComicBook)specificBook;
    
    ComicBook cb = specificBook as ComicBook;
    if (cb != null) {
       // ...
    }
    
    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
    }
    
    Contact contact = new Contact { Name = "Abhinav"};
    var context = new DataContext();
    context.Contacts.Add(contact);
    context.SaveChanges(); // NullReferenceException at this line
    
    public class DataContext : DbContext 
    {
        public DbSet<Contact> Contacts {get; set;}
    }
    
    public partial class Contact 
    {
        public string Name {get; set;}
    }
    
    var x = myString.Trim();
    
    var x = str1.Trim() + str2.Trim();
    
    string str = string.Empty;
    str.ToLower(); // throw null reference exception
    
    Public Class Person {
        public string Name { get; set; }
    }
    Person objPerson;
    objPerson.Name  /// throw Null refernce Exception 
    
    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();
        }
    }
    
    object o = null;
    DateTime d = (DateTime)o;  // 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.
    
    public X { get; set; }
    
    public void InvokeX()
    {
        X.DoSomething(); // if X value is null, you will get a NullReferenceException
    }
    
    //Using code contracts:
    [ContractInvariantMethod]
    protected void ObjectInvariant() 
    {
        Contract.Invariant(X != null);
        //...
    }
    
    @{
        MyEntity M = new MyEntity();
    }
    @RenderPage("_MyOtherView.cshtml", M); // error in _MyOtherView, the Model was Null
    
    @{
        MyEntity M = new MyEntity();
    }
    @Html.Partial("_MyOtherView.cshtml", M);
    
    @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(var M in MyEntities){
        ...
    }
    
    if (i == null) {
        // Handle this
    }
    
    public void DoSomething(MyObject obj) {
        if(obj == null) 
        {
            throw new ArgumentNullException("obj", "Need a reference to obj.");
        }
    }
    
    public void DoSometing([NotNull] obj)
    
    [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 };
        }
    }
    
    NotNull<Person> person = null; // throws exception
    NotNull<Person> person = new Person(); // OK
    NotNull<Person> person = GetPerson(); // throws exception if GetPerson() returns null
    
    Person person = new Person { Name = "John" };
    WriteName(person);
    
    public static void WriteName(NotNull<Person> person)
    {
        Console.WriteLine(person.Value.Name);
    }
    
    Person person = GetPerson();
    
    public static NotNull<Person> GetPerson()
    {
        return new Person { Name = "John" };
    }
    
    Person person = (NotNull<Person>)GetPerson();
    
    public static Person GetPerson()
    {
        return new Person { Name = "John" };
    }
    
    [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();
    
    var address = country?.State?.County?.City;
    
    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;
        }        
    }
    
    public Class myClass
    {
       public int prop1 {get;set;}
    }
    
    public class Demo
    {
         public void testMethod()
         {
            myClass ref = null;
            ref.prop1 = 1;  // This line throws an error
         }
    }
    
    public class Demo
    {
         public void testMethod()
         {
            myClass ref = null;
            ref = new myClass();
            ref.prop1 = 1;
         }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            string str = null;
            Console.WriteLine(str.Length);
            Console.ReadLine();
        }
    }
    
    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");
        }
    }
    
      var name = p?.Spouse?.FirstName;
    
        if (p != null)
        {
            if (p.Spouse != null)
            {
                name = p.Spouse.FirstName;
            }
        }