.NET[C#]中NullReferenceException(未將對象引用到實例)是什麼問題?如何修復處理?

問題分析

C#中的開發中,若是遇到「NullReferenceException」或者「未將對象引用到實例」這樣的提示,那麼是你的程序代碼正在試圖訪問一個null的引用類型的實體而拋出的異常。可能的緣由有:數組

情景一 未實例化引用類型實體

忘記了實例化一個引用類型。 在下面的示例中,names聲明,但決不實例化:ide

using System;
using System.Collections.Generic;

public class Example
{
   public static void Main(string[] args)
   {
      int value = Int32.Parse(args[0]);
      List<String> names;
      names.Add("Major Major Major");       
   }
}

此例中的 names在使用以前並無初始化,修復後的:this

using System;
using System.Collections.Generic;

public class Example
{
   public static void Main()
   {
      List<String> names = new List<String>();
      names.Add("Major Major Major");
   }
}

情景二 泛型連寫

以下代碼:rest

ref1.ref2.ref3.member

若是ref1 或者 ref2 或者 ref3任意一個爲空時,此代碼均會拋出NullReferenceException(未將對象引用到實例)的異常錯誤。咱們能夠重寫這個表達式來檢查如下的r1,r2,r3是否爲null:code

var r1 = ref1;    
var r2 = r1.ref2;
var r3 = r2.ref3;
r3.member

情景三 類的實例未初始化

以下代碼:orm

public class Book {
    public string Title { get; set; }
}
public class Example {
    public void Foo() {
        Book b1;
        string title = b1.Title; 
    }
}

其中,Example類中的b1並未實例化,會拋出NullReferenceException(未將對象引用到實例)異常,解決方法:對象

使用new關鍵字來實例化b1對象

修復後的代碼:生命週期

public class Book {
    public string Title { get; set; }
}
public class Example {
    public void Foo() {
        Book b1 = new Book();
        string title = b1.Title;
    }
}

情景四 間接引用

以下代碼:事件

public class Person {
    public int Age { get; set; }
}
public class Book {
    public Person Author { get; set; }
}
public class Example {
    public void Foo() {
        Book b1 = new Book();
        int authorAge = b1.Author.Age; 
    }
}

這裏的 Example 類中的b1已被實例化,但若是咱們運行程序,依然會拋出NullReferenceException(未將對象引用到實例)異常。是由於 Book 類中包含了另一個引用類 Person 但並無被實例化,解決方式能夠在Book的構造器中直接實例化,如:開發

public class Person {
    public int Age { get; set; }
}
public class Book {
    public Book(){
        Author = new Person();
    }
    public Person Author { get; set; }
}
public class Example {
    public void Foo() {
        Book b1 = new Book();
        int authorAge = b1.Author.Age; 
    }
}

固然,你也能夠在使用 Book 這個類的實例時再來初始化 Person 這個引用類,以下:

public class Person {
    public int Age { get; set; }
}
public class Book {
    public Person Author { get; set; }
}
public class Example {
    public void Foo() {
        Book b1 = new Book();
        b1.Author = new Person();
        int authorAge = b1.Author.Age; 
    }
}

情景五 數組爲null

int[] numbers = null;
int n = numbers[0];
Person[] people = new Person[5];
people[0].Age = 20
long[][] array = new long[1][];
array[0][0] = 3;

這三種數組的定義均爲null,拋出NullReferenceException(未將對象引用到實例)的異常

情景六 數據字典爲null

Dictionary<string, int> agesForNames = null;
int age = agesForNames["Bob"];

這裏的 agesForNames字典爲 null,拋出NullReferenceException(未將對象引用到實例)的異常,使用new關鍵字來初始化:

Dictionary<string, int> agesForNames = new Dictionary<string, int>();
int age = agesForNames["Bob"];

情景七 集合爲null

public class Person {
    public string Name { get; set; }
}
var people = new List<Person>();
people.Add(null);
var names = from p in people select p.Name;
string firstName = names.First();

以上代碼會在 names.First() 處理拋出異常,由於咱們在

people.Add(null);
添加了null值

情景八 事件(Event)爲null

public class Demo
{
    public event EventHandler StateChanged;

    protected virtual void OnStateChanged(EventArgs e)
    {        
        StateChanged(this, e);
    }
}

若是外部實例沒有註冊 StateChanged 事件,那麼調用 StateChanged(this, e); 會拋出NullReferenceException(未將對象引用到實例),修復方法:

public class Demo
{
    public event EventHandler StateChanged;

    protected virtual void OnStateChanged(EventArgs e)
    {      
        if(StateChanged != null)
        {  
            StateChanged(this, e);
        }
    }
}

情景九 重複的變量名

若是全局變量和局部變量的名稱是同樣的,那麼你的全局變量就可能永遠不會被賦值,以下:

public class Form1 {
    private Customer customer;

    private void Form1_Load(object sender, EventArgs e) {
        Customer customer = new Customer();
        customer.Name = "John";
    }

    private void Button_Click(object sender, EventArgs e) {
        MessageBox.Show(customer.Name);
    }
}

請使用不一樣的變量名稱來修復:

private Customer _customer;

情景二 ASP.NET生命週期

public partial class Issues_Edit : System.Web.UI.Page
{
    protected TestIssue myIssue;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            // 只有頁面首次加載時執行,點擊按鈕時不會被執行
            myIssue = new TestIssue(); 
        }
    }

    protected void SaveButton_Click(object sender, EventArgs e)
    {
        myIssue.Entry = "NullReferenceException here!";
    }
}

情景十一 ASP.NET Session的值爲null

string firstName = Session["FirstName"].ToString();

若是Session["FirstName"]沒有被賦值,則會拋出NullReferenceException(未將對象引用到實例)的異常。

情景十二 ASP.NET 視圖模式爲null

// Controller[控制器]
public class Restaurant:Controller
{
    public ActionResult Search()
    {
         return View();  // Forgot the provide a Model here.
    }
}

// Razor[視圖頁面]
@foreach (var restaurantSearch in Model.RestaurantSearch)  //拋出異常
{
}

<p>@Model.somePropertyName</p> <!-- 拋出異常 -->

關於.NET[C#]中NullReferenceException(未將對象引用到實例)總結到這裏,若是你遇到在不一樣的情景遇到一樣的異常,歡迎反饋、交流。

相關文章
相關標籤/搜索