什么是NullReferenceException,如何解决?

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

你调用的对象是空的。

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

原因是什么?

底线

你正在尝试使用null (或VB.NET中Nothing )的东西。 这意味着你要么将它设置为null ,要么你从来没有把它设置为任何东西。

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

本文的其余部分将更详细地介绍许多程序员经常犯的错误,这可能会导致NullReferenceException

进一步来说

抛出一个NullReferenceException的运行时总是意味着同样的事情:你正在尝试使用一个引用,并且引用没有被初始化(或者它被初始化了,但不再被初始化)。

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

 string foo = null; foo.ToUpper(); 

这将在第二行中抛出一个NullReferenceException ,因为您不能在指向nullstring引用上调用实例方法ToUpper()

debugging

你如何find一个NullReferenceException的来源? 除了查看exception本身,这些exception本身将会发生在它发生的位置,Visual Studio中debugging的一般规则也适用:放置战略断点并检查variables ,方法是将鼠标hover在其名称上,打开(快速)观察窗口或使用各种debugging面板,如本地和汽车。

如果您想查找引用的位置或未设置,请右键单击其名称并select“查找所有引用”。 然后,您可以在每个find的位置放置一个断点,并使用附加的debugging器运行程序。 每当debugging器断开这样一个断点,就需要确定是否期望引用是非空值,检查variables并validation它是否指向实例。

通过以这种方式遵循程序stream程,您可以find实例不应该为null的位置,以及为什么它没有正确设置。

例子

可能引发exception的一些常见情况:

通用

 ref1.ref2.ref3.member 

如果ref1或ref2或ref3为空,那么您将得到一个NullReferenceException 。 如果你想解决这个问题,那么通过将expression式重写为更简单的等价forms来找出哪一个是空的:

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

特别是,在HttpContext.Current.User.Identity.NameHttpContext.Current可能为null,或者User属性可能为null,或者Identity属性可能为null。

类实例

创build引用(类)types的variables时,默认情况下设置为null

 public class Book { public string Title { get; set; } } public class Example { public void Foo() { Book b1; string title = b1.Title; // You never initialized the b1 variable. // there is no book to get the title from. } } 

类typesvariables必须被初始化或设置为已经存在的类实例。 初始化是通过使用new关键字来完成的。

 Book b1 = new Book(); 

间接

 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; // You never initialized the Author property. // there is no Person to get an Age from. } } 

如果你想避免child(Person)空引用,你可以在父(Book)对象的构造函数中初始化它。

这同样适用于嵌套对象初始值设定项:

 Book b1 = new Book { Author = { Age = 45 } }; 

当使用new关键字时,它只创buildBook的新实例,而不创buildPerson的新实例,所以Author的属性仍然为null

排列

 int[] numbers = null; int n = numbers[0]; // numbers is null. There is no array to index. 

数组元素

 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. 

锯齿的数组

 long[][] array = new long[1][]; array[0][0] = 3; // is null because only the first dimension is yet initialized. // Use array[0] = new long[2]; first. 

集合/列表/字典

 Dictionary<string, int> agesForNames = null; int age = agesForNames["Bob"]; // agesForNames is null. // There is no Dictionary to perform the lookup. 

范围variables(间接/延迟)

 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(); // Exception is thrown here, but actually occurs // on the line above. "p" is null because the // first element we added to the list is null. 

活动

 public class Demo { public event EventHandler StateChanged; protected virtual void OnStateChanged(EventArgs e) { StateChanged(this, e); // Exception is thrown here // if no event handlers have been attached // to StateChanged event } } 

错误的命名约定:

如果您将字段命名为与当地人不同,则可能意识到您从未初始化该字段。

 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) { // Only called on first load, not when button clicked myIssue = new TestIssue(); } } protected void SaveButton_Click(object sender, EventArgs e) { myIssue.Entry = "NullReferenceException here!"; } } 

ASP.NET会话值

 // if the "FirstName" session value has not yet been set, // then this line will throw a NullReferenceException string firstName = Session["FirstName"].ToString(); 

ASP.NET MVC空视图模型

如果在ASP.NET MVC视图中引用@Model的属性时发生exception,则需要了解在return视图时, Model会在操作方法中设置。 从控制器返回一个空模型(或模型属性)时,当视图访问它时会发生exception:

 // Controller public class Restaurant:Controller { public ActionResult Search() { return View(); // Forgot the provide a Model here. } } // Razor view @foreach (var restaurantSearch in Model.RestaurantSearch) // Throws. { } <p>@Model.somePropertyName</p> <!-- Also throws --> 

WPF控件创build顺序和事件

WPF控件是在调用InitializeComponent中按照它们出现在可视化树中的顺序创build的。 在使用事件处理程序等早期创build的控件的情况下会引发一个NullReferenceException ,该事件处理程序等等,在InitializeComponent中引用了晚期创build的控件。

例如 :

 <Grid> <!-- Combobox declared first --> <ComboBox Name="comboBox1" Margin="10" SelectedIndex="0" SelectionChanged="comboBox1_SelectionChanged"> <ComboBoxItem Content="Item 1" /> <ComboBoxItem Content="Item 2" /> <ComboBoxItem Content="Item 3" /> </ComboBox> <!-- Label declared later --> <Label Name="label1" Content="Label" Margin="10" /> </Grid> 

这里comboBox1是在label1之前创build的。 如果comboBox1_SelectionChanged试图引用label1,它还不会被创build。

 private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e) { label1.Content = comboBox1.SelectedIndex.ToString(); // NullReference here!! } 

更改XAML中声明的顺序(即,在comboBox1之前列出label1 ,忽略devise原理的问题,至less可以解决NullReferenceException

as投射

 var myThing = someObject as Thing; 

这不会抛出InvalidCastException,但在转换失败时(以及someObject本身为null)时返回null。 所以要注意这一点。

LINQ FirstOrDefault()和SingleOrDefault()

当没有任何东西的时候,普通版本First()Single()抛出exception。 在这种情况下,“OrDefault”版本返回null。 所以要注意这一点。

的foreach

当您尝试迭代空收集时foreach抛出。 通常由返回集合的方法导致意外的null结果。

  List<int> list = null; foreach(var v in list) { } // exception 

更现实的例子 – 从XML文档中select节点。 如果没有find节点,将抛出,但初始debugging显示所有属性都是有效的:

  foreach (var node in myData.MyXml.DocumentNode.SelectNodes("//Data")) 

避免的方法

显式检查null并忽略空值。

如果您希望引用有时为空,则可以在访问实例成员之前检查它是否为null

 void PrintName(Person p) { if (p != null) { Console.WriteLine(p.Name); } } 

显式检查null并提供一个默认值。

方法调用你期望返回一个实例可以返回null ,例如当找不到的对象时。 在这种情况下,您可以select返回默认值:

 string GetCategory(Book b) { if (b == null) return "Unknown"; return b.Category; } 

显式检查方法调用中的null并抛出一个自定义exception。

你也可以抛出一个自定义的exception,只在调用代码中捕获它:

 string GetCategory(string bookTitle) { var book = library.FindBook(bookTitle); // This may return null if (book == null) throw new BookNotFoundException(bookTitle); // Your custom exception return book.Category; } 

如果某个值永远不能为null ,请使用Debug.Assert ,以便在发生exception时尽早发现问题。

当你在开发过程中知道一个方法可能可以,但从不应该返回null ,可以使用Debug.Assert()在发生时尽快中断:

 string GetTitle(int knownBookID) { // You know this should never return null. var book = library.GetBook(knownBookID); // Exception will occur on the next line instead of at the end of this method. Debug.Assert(book != null, "Library didn't return a book for known book ID."); // Some other code return book.Title; // Will never throw NullReferenceException in Debug mode. } 

虽然这个检查不会在你的发布版本中结束 ,但是当它在发布模式下运行时, book == null时候会导致它再次抛出NullReferenceException

使用GetValueOrDefault()作为可为空的值types时提供默认值,当它们为null

 DateTime? appointment = null; Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now)); // Will display the default value provided (DateTime.Now), because appointment is null. appointment = new DateTime(2022, 10, 20); Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now)); // Will display the appointment date, not the default 

使用空合并运算符: ?? [C#]或If() [VB]。

遇到null时提供默认值的简写:

 IService CreateService(ILogger log, Int32? frobPowerLevel) { var serviceImpl = new MyService(log ?? NullLog.Instance); // Note that the above "GetValueOrDefault()" can also be rewritten to use // the coalesce operator: serviceImpl.FrobPowerLevel = frobPowerLevel ?? 5; } 

使用null条件运算符: ?. (在C#6和VB.NET 14中可用):

这有时也被称为安全导航或埃尔维斯(在它的形状之后)操作员。 如果运算符左侧的expression式为空,则右侧将不计算,而返回null。 这意味着这样的情况:

 var title = person.Title.ToUpper(); 

如果这个人没有一个标题,这将会抛出一个exception,因为它试图在一个空值的属性上调用ToUpper

在C#5及以下版本中,可以用以下方式来保护:

 var title = person.Title == null ? null : person.Title.ToUpper(); 

现在titlevariables将是null而不是引发exception。 C#6为此引入了更短的语法:

 var title = person.Title?.ToUpper(); 

这将导致titlevariables为null ,如果person.Titlenull则不会调用ToUpper

当然,您仍然需要检查null的title ,或者使用空条件运算符和空合并运算符( ?? )来提供默认值:

 // regular null check int titleLength = 0; if (title != null) titleLength = title.Length; // If title is null, this would throw NullReferenceException // combining the `?` and the `??` operator int titleLength = title?.Length ?? 0; 

NullReferenceexception – Visual Basic

Visual BasicNullReference ExceptionC#中NullReference Exception没有区别。 毕竟,它们都报告了它们都使用的.NET Framework中定义的相同exception。 Visual Basic独特的原因很less(可能只有一个)。

这个答案将使用Visual Basic的术语,语法和上下文。 使用的例子来自大量的Stack Overflow问题。 这是通过使用在post中常见的情况来最大化相关性。 还为可能需要它的人提供了一点解释。 类似于你的例子可能在这里列出。

注意:

  1. 这是基于概念的:没有代码可以粘贴到您的项目中。 它旨在帮助您了解导致NullReferenceException (NRE)的原因,如何find它,如何解决该问题,以及如何避免它。 NRE可能会导致很多方面,所以这不太可能是你唯一的遭遇。
  2. 这些例子(来自Stack Overflow的post)并不总是显示出最好的方式来做一些事情。
  3. 通常,使用最简单的补救措施。

基本含义

消息“对象未设置为对象的实例”表示您正在尝试使用尚未初始化的对象。 这归结为其中之一:

  • 你的代码声明了一个对象variables,但它没有初始化它(创build一个实例或“ 实例化 ”它)
  • 你的代码假设会初始化一个对象,没有
  • 其他代码可能过早地使仍在使用的对象无效

寻找原因

由于问题是一个Nothing的对象引用,答案是检查他们找出哪一个。 然后确定它为什么没有被初始化。 将鼠标放在各种variables上,Visual Studio(VS)将显示它们的值 – 罪魁祸首将是Nothing

IDE调试显示

你也应该删除相关代码中的任何Try / Catch块,尤其是那些Catch块中没有任何内容的代码块。 这会导致您的代码在尝试使用Nothing的对象时崩溃。 这是你想要的,因为它会识别问题的确切位置 ,并允许你识别造成它的对象。

Catch中的MsgBox显示Error while...将没有什么帮助。 这个方法也会导致堆栈溢出问题,因为你不能描述实际的exception,涉及的对象,甚至是代码行。

你也可以使用Locals WindowDebug – > Windows – > Locals )来检查你的对象。

一旦你知道问题出在什么地方,通常很容易解决问题,而且比发布一个新问题更快。

也可以看看:

  • 断点
  • MSDN:如何:使用Try / Catch块来捕获exception
  • MSDN:exception的最佳实践

示例和补救措施

类对象/创build实例

 Dim reg As CashRegister ... TextBox1.Text = reg.Amount ' NRE 

问题是Dim不会创build一个CashRegister 对象 ; 它只声明一个名为该types的reg的variables。 声明一个对象variables并创build一个实例是两回事。

补救

New运算符通常可用于在声明它时创build实例:

 Dim reg As New CashRegister ' [New] creates instance, invokes the constructor ' Longer, more explicit form: Dim reg As CashRegister = New CashRegister 

以后只适合于创build实例:

 Private reg As CashRegister ' Declare ... reg = New CashRegister() ' Create instance 

注意: 不要在过程中再次使用Dim ,包括构造函数( Sub New ):

 Private reg As CashRegister '... Public Sub New() '... Dim reg As New CashRegister End Sub 

这将创build一个局部variablesreg ,它只存在于该上下文(sub)中。 您将在其他地方使用的模块级别为Scoperegvariables将保持为Nothing

New运算符的缺失是NullReference Exceptions的第一个原因

Visual Basic尝试使用New重复清除该进程:使用New运算符创build一个对象并调用Sub New – 构造函数 – 您的对象可以在其中执行任何其他初始化。

要清楚, Dim (或Private )只声明一个variables及其Type 。 variables的范围 – 无论它是存在于整个模块/类还是程序本地的 – 由其声明的位置决定。 Private | Friend | Public Private | Friend | Public定义访问级别,而不是范围

有关更多信息,请参阅:

  • 新运营商
  • 在Visual Basic中的作用域
  • 在Visual Basic中访问级别
  • 值types和引用types

数组

数组也必须被实例化:

 Private arr as String() 

这个数组只是被声明的,没有被创build。 有几种方法来初始化一个数组:

 Private arr as String() = New String(10){} ' or Private arr() As String = New String(10){} ' For a local array (in a procedure) and using 'Option Infer': Dim arr = New String(10) {} 

注意:从VS 2010开始,当使用文字和Option Infer初始化本地数组时, As <Type>New元素是可选的:

 Dim myDbl As Double() = {1.5, 2, 9.9, 18, 3.14} Dim myDbl = New Double() {1.5, 2, 9.9, 18, 3.14} Dim myDbl() = {1.5, 2, 9.9, 18, 3.14} 

数据types和数组大小是从正在分配的数据中推断出来的。 类/模块级声明仍然需要As <Type> with Option Strict

 Private myDoubles As Double() = {1.5, 2, 9.9, 18, 3.14} 

示例:类对象数组

 Dim arrFoo(5) As Foo For i As Integer = 0 To arrFoo.Count - 1 arrFoo(i).Bar = i * 10 ' Exception Next 

该数组已经创build,但Foo对象没有。

补救

 For i As Integer = 0 To arrFoo.Count - 1 arrFoo(i) = New Foo() ' Create Foo instance arrFoo(i).Bar = i * 10 Next 

使用List(Of T)将会使得没有一个有效对象的元素变得相当困难:

 Dim FooList As New List(Of Foo) ' List created, but it is empty Dim f As Foo ' Temporary variable for the loop For i As Integer = 0 To 5 f = New Foo() ' Foo instance created f.Bar = i * 10 FooList.Add(f) ' Foo object added to list Next 

有关更多信息,请参阅:

  • 期权推断声明
  • 在Visual Basic中的作用域
  • 在Visual Basic中的数组

列表和集合

.NET集合(其中有许多种类 – 列表,字典等)也必须实例化或创build。

 Private myList As List(Of String) .. myList.Add("ziggy") ' NullReference 

你出于同样的原因得到相同的exception – myList只声明,但没有创build实例。 补救措施是一样的:

 myList = New List(Of String) ' Or create an instance when declared: Private myList As New List(Of String) 

一个普遍的疏忽是使用集合的Type

 Public Class Foo Private barList As List(Of Bar) Friend Function BarCount As Integer Return barList.Count End Function Friend Sub AddItem(newBar As Bar) If barList.Contains(newBar) = False Then barList.Add(newBar) End If End Function 

任一过程都将导致一个NRE,因为barList只是被声明的,没有实例化。 创buildFoo的实例也不会创build内部barList的实例。 它可能是在构造函数中这样做的意图:

 Public Sub New ' Constructor ' Stuff to do when a new Foo is created... barList = New List(Of Bar) End Sub 

和以前一样,这是不正确的:

 Public Sub New() ' Creates another barList local to this procedure Dim barList As New List(Of Bar) End Sub 

有关更多信息,请参见List(Of T)类 。


数据提供者对象

使用数据库为NullReference提供了很多机会,因为可以同时使用许多对象( CommandConnectionTransactionDatasetDataTableDataRows ….)。 注意:你使用的数据提供者无关紧要–MySQL,SQL Server,OleDB等 – 概念是相同的。

例1

 Dim da As OleDbDataAdapter Dim ds As DataSet Dim MaxRows As Integer con.Open() Dim sql = "SELECT * FROM tblfoobar_List" da = New OleDbDataAdapter(sql, con) da.Fill(ds, "foobar") con.Close() MaxRows = ds.Tables("foobar").Rows.Count ' Error 

像以前一样, ds数据集对象被声明,但是一个实例从未被创build。 DataAdapter将填充现有的DataSet ,而不是创build一个。 在这种情况下,由于ds是局部variables, 因此IDE会警告您可能会发生这种情况:

IMG

当被声明为模块/类级别variables时,与con似乎一样,编译器无法知道对象是否由上游过程创build。 不要忽视警告。

补救

 Dim ds As New DataSet 

例2

 ds = New DataSet da = New OleDBDataAdapter(sql, con) da.Fill(ds, "Employees") txtID.Text = ds.Tables("Employee").Rows(0).Item(1) txtID.Name = ds.Tables("Employee").Rows(0).Item(2) 

一个错字是这里的一个问题: Employees vs Employee 。 没有创build名为“Employee”的DataTable ,因此尝试访问它的NullReferenceException结果。 另外一个潜在的问题是假定在SQL包含一个WHERE子句的时候会有这样的Items

补救

由于这使用一个表,使用Tables(0)将避免拼写错误。 检查Rows.Count也可以帮助:

 If ds.Tables(0).Rows.Count > 0 Then txtID.Text = ds.Tables(0).Rows(0).Item(1) txtID.Name = ds.Tables(0).Rows(0).Item(2) End If 

Fill是一个函数,返回受影响的Rows数,也可以被testing:

 If da.Fill(ds, "Employees") > 0 Then... 

例3

 Dim da As New OleDb.OleDbDataAdapter("SELECT TICKET.TICKET_NO, TICKET.CUSTOMER_ID, ... FROM TICKET_RESERVATION AS TICKET INNER JOIN FLIGHT_DETAILS AS FLIGHT ... WHERE [TICKET.TICKET_NO]= ...", con) Dim ds As New DataSet da.Fill(ds) If ds.Tables("TICKET_RESERVATION").Rows.Count > 0 Then 

DataAdapter将提供如上例所示的TableNames ,但不会从SQL或数据库表中parsing名称。 因此, ds.Tables("TICKET_RESERVATION")引用一个不存在的表。

补救措施是一样的,参考表索引:

 If ds.Tables(0).Rows.Count > 0 Then 

另请参阅DataTable类 。


对象path/嵌套

 If myFoo.Bar.Items IsNot Nothing Then ... 

代码只是testingItemsmyFooBar也可能是没有。 补救措施是一次testing一个对象的整个链或path:

 If (myFoo IsNot Nothing) AndAlso (myFoo.Bar IsNot Nothing) AndAlso (myFoo.Bar.Items IsNot Nothing) Then .... 

AndAlso也很重要。 一旦遇到第一个False条件,后续testing将不会执行。 这允许代码一次性安全地“钻取”到一个“级别”的对象中,只有在(和if) myFoo被确定为有效之后才评估myFoo.Bar 。 编码复杂对象时,对象链或path可能会变得很长:

 myBase.myNodes(3).Layer.SubLayer.Foo.Files.Add("somefilename") 

无法引用null对象的任何“下游”。 这也适用于控制:

 myWebBrowser.Document.GetElementById("formfld1").InnerText = "some value" 

在这里, myWebBrowserDocument可能是Nothing,或者formfld1元素可能不存在。


UI控件

 Dim cmd5 As New SqlCommand("select Cartons, Pieces, Foobar " _ & "FROM Invoice where invoice_no = '" & _ Me.ComboBox5.SelectedItem.ToString.Trim & "' And category = '" & _ Me.ListBox1.SelectedItem.ToString.Trim & "' And item_name = '" & _ Me.ComboBox2.SelectedValue.ToString.Trim & "' And expiry_date = '" & _ Me.expiry.Text & "'", con) 

除此之外,这段代码并不预期用户可能没有在一个或多个UI控件中select一些东西。 ListBox1.SelectedItem可能是Nothing ,所以ListBox1.SelectedItem.ToString将导致一个NRE。

补救

在使用之前validation数据(也使用Option Strict和SQL参数):

 Dim expiry As DateTime ' for text date validation If (ComboBox5.SelectedItems.Count > 0) AndAlso (ListBox1.SelectedItems.Count > 0) AndAlso (ComboBox2.SelectedItems.Count > 0) AndAlso (DateTime.TryParse(expiry.Text, expiry) Then '... do stuff Else MessageBox.Show(...error message...) End If 

或者,您可以使用(ComboBox5.SelectedItem IsNot Nothing) AndAlso...


Visual Basic窗体

 Public Class Form1 Private NameBoxes = New TextBox(5) {Controls("TextBox1"), _ Controls("TextBox2"), Controls("TextBox3"), _ Controls("TextBox4"), Controls("TextBox5"), _ Controls("TextBox6")} ' same thing in a different format: Private boxList As New List(Of TextBox) From {TextBox1, TextBox2, TextBox3 ...} ' Immediate NRE: Private somevar As String = Me.Controls("TextBox1").Text 

这是获得NRE的一个相当常见的方法。 在C#中,根据编码方式,IDE将报告Controls在当前上下文中不存在,或者“不能引用非静态成员”。 所以,在某种程度上,这是一个VB的情况。 这也是复杂的,因为它可能导致级联失败。

数组和集合不能以这种方式初始化。 此初始化代码将构造函数创buildFormControls 之前运行。 结果是:

  • 列表和集合将只是空的
  • 该数组将包含Nothing的五个元素
  • somevar赋值将导致立即NRE,因为Nothing没有.Text属性

稍后引用数组元素将导致NRE。 如果您在Form_Load执行此操作,由于存在奇怪的错误,IDE在发生exception时可能不会报告exception。 当你的代码尝试使用数组时,将会popup一个例外。 这个“沉默的例外” 在这篇文章中详细介绍 。 就我们的目的而言,关键在于,当创build表单( Sub NewForm Load事件)时发生灾难性事件时,exception可能不会被报告,代码会退出过程并只显示表单。

由于在NRE之后, Sub NewForm Load事件中没有其他代码会运行,所以还有很多其他的东西可能未被初始化。

 Sub Form_Load(..._ '... Dim name As String = NameBoxes(2).Text ' NRE ' ... ' More code (which will likely not be executed) ' ... End Sub 

请注意,这适用于任何以及所有控制和组件引用,因为它们是非法的:

 Public Class Form1 Private myFiles() As String = Me.OpenFileDialog1.FileName & ... Private dbcon As String = OpenFileDialog1.FileName & ";Jet Oledb..." Private studentName As String = TextBox13.Text 

部分补救措施

很奇怪VB没有提供警告,但补救措施是在表单级别声明容器,但是当控件确实存在时,在表单加载事件处理程序中初始化它们。 只要您的代码在InitializeComponent调用之后,就可以在Sub New完成:

 ' Module level declaration Private NameBoxes as TextBox() Private studentName As String ' Form Load, Form Shown or Sub New: ' ' Using the OP's approach (illegal using OPTION STRICT) NameBoxes = New TextBox() {Me.Controls("TextBox1"), Me.Controls("TestBox2"), ...) studentName = TextBox32.Text ' For simple control references 

数组代码可能还没有走出困境。 Me.Controls找不到在容器控件(如GroupBoxPanel )中的任何控件; 他们将在该Panel或GroupBox的Controls集合中。 控件名称拼写错误时( "TeStBox2" )也不会返回控件。 在这种情况下, Nothing将再次存储在这些数组元素中,并且当您尝试引用它时将导致NRE。

这些应该很容易find,你知道你在找什么: VS显示你的方式错误

“Button2”驻留在Panel

补救

而不是按名称使用窗体的Controls集合间接引用,请使用控件引用:

 ' Declaration Private NameBoxes As TextBox() ' Initialization - simple and easy to read, hard to botch: NameBoxes = New TextBox() {TextBox1, TextBox2, ...) ' Initialize a List NamesList = New List(Of TextBox)({TextBox1, TextBox2, TextBox3...}) ' or NamesList = New List(Of TextBox) NamesList.AddRange({TextBox1, TextBox2, TextBox3...}) 

函数没有返回

 Private bars As New List(Of Bars) ' Declared and created Public Function BarList() As List(Of Bars) bars.Clear If someCondition Then For n As Integer = 0 to someValue bars.Add(GetBar(n)) Next n Else Exit Function End If Return bars End Function 

这种情况下,IDE会警告您“ 不是所有的path都返回一个值,并且可能导致NullReferenceException ”。 您可以通过将Exit Functionreplace为Return Nothing来禁止警告,但这并不能解决问题。 当someCondition = False时,任何试图使用返回someCondition = False都会导致NRE:

 bList = myFoo.BarList() For Each b As Bar in bList ' EXCEPTION ... 

补救

使用Return bListreplaceExit Function中的Exit Function 。 返回一个 List与返回Nothing 。 如果返回的对象有可能是Nothing ,请在使用之前进行testing:

  bList = myFoo.BarList() If bList IsNot Nothing Then... 

很难实现Try / Catch

一个执行得不好的Try / Catch可以隐藏问题所在并导致新问题:

 Dim dr As SqlDataReader Try Dim lnk As LinkButton = TryCast(sender, LinkButton) Dim gr As GridViewRow = DirectCast(lnk.NamingContainer, GridViewRow) Dim eid As String = GridView1.DataKeys(gr.RowIndex).Value.ToString() ViewState("username") = eid sqlQry = "select FirstName, Surname, DepartmentName, ExtensionName, jobTitle, Pager, mailaddress, from employees1 where username='" & eid & "'" If connection.State <> ConnectionState.Open Then connection.Open() End If command = New SqlCommand(sqlQry, connection) 'More code fooing and barring dr = command.ExecuteReader() If dr.Read() Then lblFirstName.Text = Convert.ToString(dr("FirstName")) ... End If mpe.Show() Catch Finally command.Dispose() dr.Close() ' <-- NRE connection.Close() End Try 

这是一个没有按预期创build的对象的情况,但也显示了一个空的Catch的计数器的有用性。

SQL中有一个额外的逗号(在'mailaddress'之后),导致.ExecuteReader出现exception。 在Catch没有做什么之后, Finally尝试执行清理,但由于您不能Close一个空的DataReader对象,所以会产生一个全新的NullReferenceException

一个空的Catch块是魔鬼的游乐场。 这个OP很困惑他为什么要在Finally一块获得NRE。 在其他情况下,一个空的Catch可能会导致更糟糕的事情发生在更远的地方,导致你花时间在错误的地方看错问题。 (上述“无声的例外”提供了相同的娱乐价值。)

补救

不要使用空的Try / Catch块 – 让代码崩溃,这样你可以a)找出原因b)确定位置c)应用适当的补救措施。 Try / Catch块不打算隐藏唯一有资格修复它们的人的exception – 开发人员。


DBNull与Nothing不一样

 For Each row As DataGridViewRow In dgvPlanning.Rows If Not IsDBNull(row.Cells(0).Value) Then ... 

IsDBNull函数用于testing一个值是否等于System.DBNull : 从MSDN:

System.DBNull值表示该对象表示丢失或不存在的数据。 DBNull与Nothing不一样,表示一个variables尚未初始化。

补救

 If row.Cells(0) IsNot Nothing Then ... 

和以前一样,你可以testingNothing,然后获得一个特定的值:

 If (row.Cells(0) IsNot Nothing) AndAlso (IsDBNull(row.Cells(0).Value) = False) Then 

例2

 Dim getFoo = (From f In dbContext.FooBars Where f.something = something Select f).FirstOrDefault If Not IsDBNull(getFoo) Then If IsDBNull(getFoo.user_id) Then txtFirst.Text = getFoo.first_name Else ... 

FirstOrDefault returns the first item or the default value, which is Nothing for reference types and never DBNull :

 If getFoo IsNot Nothing Then... 

控制

 Dim chk As CheckBox chk = CType(Me.Controls(chkName), CheckBox) If chk.Checked Then Return chk End If 

If a CheckBox with chkName can't be found (or exists in a GroupBox ), then chk will be Nothing and be attempting to reference any property will result in an exception.

Remedy

 If (chk IsNot Nothing) AndAlso (chk.Checked) Then ... 

The DataGridView

The DGV has a few quirks seen periodically:

 dgvBooks.DataSource = loan.Books dgvBooks.Columns("ISBN").Visible = True ' NullReferenceException dgvBooks.Columns("Title").DefaultCellStyle.Format = "C" dgvBooks.Columns("Author").DefaultCellStyle.Format = "C" dgvBooks.Columns("Price").DefaultCellStyle.Format = "C" 

If dgvBooks has AutoGenerateColumns = True , it will create the columns, but it does not name them, so the above code fails when it references them by name.

Remedy

Name the columns manually, or reference by index:

 dgvBooks.Columns(0).Visible = True 

Example 2 — Beware of the NewRow

 xlWorkSheet = xlWorkBook.Sheets("sheet1") For i = 0 To myDGV.RowCount - 1 For j = 0 To myDGV.ColumnCount - 1 For k As Integer = 1 To myDGV.Columns.Count xlWorkSheet.Cells(1, k) = myDGV.Columns(k - 1).HeaderText xlWorkSheet.Cells(i + 2, j + 1) = myDGV(j, i).Value.ToString() Next Next Next 

When your DataGridView has AllowUserToAddRows as True (the default), the Cells in the blank/new row at the bottom will all contain Nothing . Most attempts to use the contents (for example, ToString ) will result in an NRE.

Remedy

Use a For/Each loop and test the IsNewRow property to determine if it is that last row. This works whether AllowUserToAddRows is true or not:

 For Each r As DataGridViewRow in myDGV.Rows If r.IsNewRow = False Then ' ok to use this row 

If you do use a For n loop, modify the row count or use Exit For when IsNewRow is true.


My.Settings (StringCollection)

Under certain circumstances, trying to use an item from My.Settings which is a StringCollection can result in a NullReference the first time you use it. The solution is the same, but not as obvious. 考虑:

 My.Settings.FooBars.Add("ziggy") ' foobars is a string collection 

Since VB is managing Settings for you, it is reasonable to expect it to initialize the collection. It will, but only if you have previously added an initial entry to the collection (in the Settings editor). Since the collection is (apparently) initialized when an item is added, it remains Nothing when there are no items in the Settings editor to add.

Remedy

Initialize the settings collection in the form's Load event handler, if/when needed:

 If My.Settings.FooBars Is Nothing Then My.Settings.FooBars = New System.Collections.Specialized.StringCollection End If 

Typically, the Settings collection will only need to be initialized the first time the application runs. An alternate remedy is to add an initial value to your collection in Project -> Settings | FooBars , save the project, then remove the fake value.


关键点

You probably forgot the New operator.

要么

Something you assumed would perform flawlessly to return an initialized object to your code, did not.

Don't ignore compiler warnings (ever) and use Option Strict On (always).


MSDN NullReference Exception

Another scenario is when you cast a null object into a value type . For example, the code below:

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

It will throw a NullReferenceException on the cast. It seems quite obvious in the above sample, but this can happen in more "late-binding" intricate scenarios where the null object has been returned from some code you don't own, and the cast is for example generated by some automatic system.

One example of this is this simple ASP.NET binding fragment with the Calendar control:

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

Here, SelectedDate is in fact a property – of DateTime type – of the Calendar Web Control type, and the binding could perfectly return something null. The implicit ASP.NET Generator will create a piece of code that will be equivalent to the cast code above. And this will raise a NullReferenceException that is quite difficult to spot, because it lies in ASP.NET generated code which compiles fine…

It means that the variable in question is pointed at nothing. I could generate this like so:

 SqlConnection connection = null; connection.Open(); 

That will throw the error because while I've declared the variable " connection ", it's not pointed to anything. When I try to call the member " Open ", there's no reference for it to resolve, and it will throw the error.

To avoid this error:

  1. Always initialize your objects before you try to do anything with them.
  2. If you're not sure whether the object is null, check it with object == null .

JetBrains' Resharper tool will identify every place in your code that has the possibility of a null reference error, allowing you to put in a null check. This error is the number one source of bugs, IMHO.

It means your code used an object reference variable that was set to null (ie it did not reference an actual object instance).

To prevent the error, objects that could be null should be tested for null before being used.

 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 } 

Be aware that regardless of the scenario, the cause is always the same in .NET:

You are trying to use a reference variable whose value is Nothing / null . When the value is Nothing / null for the reference variable, that means it is not actually holding a reference to an instance of any object that exists on the heap.

You either never assigned something to the variable, never created an instance of the value assigned to the variable, or you set the variable equal to Nothing / null manually, or you called a function that set the variable to Nothing / null for you.

An example of this exception being thrown is: When you are trying to check something, that is null.

例如:

 string testString = null; //Because it doesn't have a value (ie it's null; "Length" cannot do what it needs to do) if (testString.Length == 0) // Throws a nullreferenceexception { //Do something } 

The .NET runtime will throw a NullReferenceException when you attempt to perform an action on something which hasn't been instantiated ie the code above.

In comparison to an ArgumentNullException which is typically thrown as a defensive measure if a method expects that what is being passed to it is not null.

More information is in C# NullReferenceException and Null Parameter .

If you have not initialized a reference type, and you want to set or read one of its properties, it will throw a NullReferenceException .

例:

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

You can simply avoid this by checking if the variable is not null:

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

To fully understand why a NullReferenceException is thrown, it is important to know the difference between value types and reference types .

So, if you're dealing with value types , NullReferenceExceptions can not occur. Though you need to keep alert when dealing with reference types !

Only reference types, as the name is suggesting, can hold references or point literally to nothing (or 'null'). Whereas value types always contain a value.

Reference types (these ones must be checked):

  • dynamic
  • object

Value types (you can simply ignore these ones):

  • 数字types
  • Integral types
  • Floating-point types
  • decimal
  • 布尔
  • User defined structs

Another case where NullReferenceExceptions can happen is the (incorrect) use of the as operator :

 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 

Here, Book and Car are incompatible types; a Car cannot be converted/cast to a Book . When this cast fails, as returns null . Using mybook after this causes a NullReferenceException .

In general, you should use a cast or as , as follows:

If you are expecting the type conversion to always succeed (ie. you know what the object should be ahead of time), then you should use a cast:

 ComicBook cb = (ComicBook)specificBook; 

If you are unsure of the type, but you want to try to use it as a specific type, then use as :

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

You are using the object that contains the null value reference. So it's giving a null exception. In the example the string value is null and when checking its length, the exception occurred.

例:

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

The exception error is:

Unhandled Exception:

System.NullReferenceException: Object reference not set to an instance of an object. at Program.Main()

Simon Mourier gave this example :

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

where an unboxing conversion (cast) from object (or from one of the classes System.ValueType or System.Enum , or from an interface type) to a value type (other than Nullable<> ) in itself gives the NullReferenceException .

In the other direction, a boxing conversion from a Nullable<> which has HasValue equal to false to a reference type, can give a null reference which can then later lead to a NullReferenceException . The classic example is:

 DateTime? d = null; var s = d.ToString(); // OK, no exception (no boxing), returns "" var t = d.GetType(); // Bang! d is boxed, NullReferenceException 

Sometimes the boxing happens in another way. For example with this non-generic extension method:

 public static void MyExtension(this object x) { x.ToString(); } 

the following code will be problematic:

 DateTime? d = null; d.MyExtension(); // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here. 

These cases arise because of the special rules the runtime uses when boxing Nullable<> instances.

While what causes a NullReferenceExceptions and approaches to avoid/fix such an exception have been addressed in other answers, what many programmers haven't learned yet is how to independently debug such exceptions during development.

In Visual Studio this is usually easy thanks to the Visual Studio Debugger .


First, make sure that the correct error is going to be caught – see How do I allow breaking on 'System.NullReferenceException' in VS2010? Note 1

Then either Start with Debugging (F5) or Attach [the VS Debugger] to Running Process . On occasion it may be useful to use Debugger.Break , which will prompt to launch the debugger.

Now, when the NullReferenceException is thrown (or unhandled) the debugger will stop (remember the rule set above?) on the line on which the exception occurred. Sometimes the error will be easy to spot.

For instance, in the following line the only code that can cause the exception is if myString evaluates to null. This can be verified by looking at the Watch Window or running expressions in the Immediate Window .

 var x = myString.Trim(); 

In more advanced cases, such as the following, you'll need to use one of the techniques above (Watch or Immediate Windows) to inspect the expressions to determine if str1 was null or if str2 was null.

 var x = str1.Trim() + str2.Trim(); 

Once where the exception is throw has been located, it's usually trivial to reason backwards to find out where the null value was [incorrectly] introduced —

Take the time required to understand the cause of the exception. Inspect for null expressions. Inspect the previous expressions which could have resulted in such null expressions. Add breakpoints and step through the program as appropriate. Use the debugger.


1 If Break on Throws is too aggressive and the debugger stops on an NPE in the .NET or 3rd-party library, Break on User-Unhandled can be used to limit the exceptions caught. Additionally, VS2012 introduces Just My Code which I recommend enabling as well.

If you are debugging with Just My Code enabled, the behavior is slightly different. With Just My Code enabled, the debugger ignores first-chance common language runtime (CLR) exceptions that are thrown outside of My Code and do not pass through My Code

Adding a case when the class name for entity used in entity framework is same as class name for a web form code-behind file.

Suppose you have a web form Contact.aspx whose codebehind class is Contact and you have an entity name Contact.

Then following code will throw a NullReferenceException when you call context.SaveChanges()

 Contact contact = new Contact { Name = "Abhinav"}; var context = new DataContext(); context.Contacts.Add(contact); context.SaveChanges(); // NullReferenceException at this line 

For the sake of completeness DataContext class

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

and Contact entity class. Sometimes entity classes are partial classes so that you can extend them in other files too.

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

The error occurs when both the entity and codebehind class are in same namespace. To fix this, rename the entity class or the codebehind class for Contact.aspx.

Reason I am still not sure about the reason. But whenever any of the entity class will extend System.Web.UI.Page this error occurs.

For discussion have a look at NullReferenceException in DbContext.saveChanges()

Another general case where one might receive this exception involves mocking classes during unit testing. Regardless of the mocking framework being used, you must ensure that all appropriate levels of the class hierarchy are properly mocked. In particular, all properties of HttpContext which are referenced by the code under test must be mocked.

See " NullReferenceException thrown when testing custom AuthorizationAttribute " for a somewhat verbose example.

I have a different perspective to answering this. This sort of answers "what else can I do to avoid it? "

When working across different layers , for example in an MVC application, a controller needs services to call business operations. In such scenarios Dependency Injection Container can be used to initialize the services to avoid the NullReferenceException . So that means you don't need to worry about checking for null and just call the services from the controller as though they will always to available (and initialized) as either a singleton or a prototype.

 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(); } } 

On the matter of "what should I do about it" , there can be many answers.

A more "formal" way of preventing such error conditions while developing is applying design by contract in your code. This means you need to set class invariants , and/or even function/method preconditions and postconditions on your system, while developing.

In short, class invariants ensure that there will be some constraints in your class that will not get violated in normal use (and therefore, the class will not get in an inconsistent state). Preconditions mean that data given as input to a function/method must follow some constraints set and never violate them, and postconditions mean that a function/method output must follow the set constraints again without ever violating them. Contract conditions should never be violated during execution of a bug-free program, therefore design by contract is checked in practice in debug mode, while being disabled in releases , to maximize the developed system performance.

This way, you can avoid NullReferenceException cases that are results of violation of the constraints set. For example, if you use an object property X in a class and later try to invoke one of its methods and X has a null value, then this will lead to NullReferenceException :

 public X { get; set; } public void InvokeX() { X.DoSomething(); // if X value is null, you will get a NullReferenceException } 

But if you set "property X must never have a null value" as method precondition, then you can prevent the scenario described before:

 //Using code contracts: [ContractInvariantMethod] protected void ObjectInvariant () { Contract.Invariant ( X != null ); //... } 

For this cause, Code Contracts project exists for .NET applications.

Alternatively, design by contract can be applied using assertions .

UPDATE: It is worth mentioning that the term was coined by Bertrand Meyer in connection with his design of the Eiffel programming language .

A NullReferenceException is thrown when we are trying to access Properties of a null object or when a string value becomes empty and we are trying to access string methods.

例如:

  1. When a string method of an empty string accessed:

     string str = string.Empty; str.ToLower(); // throw null reference exception 
  2. When a property of a null object accessed:

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

TL;DR: Try using Html.Partial instead of Renderpage


I was getting Object reference not set to an instance of an object when I tried to render a View within a View by sending it a Model, like this:

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

Debugging showed the model was Null inside MyOtherView. Until I changed it to:

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

它的工作。

Furthermore, the reason I didn't have Html.Partial to begin with was because Visual Studio sometimes throws error-looking squiggly lines under Html.Partial if it's inside a differently constructed foreach loop, even though it's not really an error:

 @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> 

But I was able to run the application with no problems with this "error". I was able to get rid of the error by changing the structure of the foreach loop to look like this:

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

Although I have a feeling it was because Visual Studio was misreading the ampersands and brackets.

What can you do about it?

There is a lot of good answers here explaining what a null reference is and how to debug it. But there is very little on how to prevent the issue or at least make it easier to catch.

Check arguments

For example, methods can check the different arguments to see if they are null and throw an ArgumentNullException , an exception obviously created for this exact purpose.

The constructor for the ArgumentNullException even takes the name of the parameter and a message as arguments so you can tell the developer exactly what the problem is.

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

Use Tools

There are also several libraries that can help. "Resharper" for example can provide you with warnings while you are writing code, especially if you use their attribute: NotNullAttribute

There's "Microsoft Code Contracts" where you use syntax like Contract.Requires(obj != null) which gives you runtime and compile checking: Introducing Code Contracts .

There's also "PostSharp" which will allow you to just use attributes like this:

 public void DoSometing([NotNull] obj) 

By doing that and making PostSharp part of your build process obj will be checked for null at runtime. See: PostSharp null check

Plain Code Solution

Or you can always code your own approach using plain old code. For example here is a struct that you can use to catch null references. It's modeled after the same concept as 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 }; } } 

You would use very similar to the same way you would use Nullable<T> , except with the goal of accomplishing exactly the opposite – to not allow 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> is implicitly cast to and from T so you can use it just about anywhere you need it. For example, you can pass a Person object to a method that takes a NotNull<Person> :

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

As you can see above as with nullable you would access the underlying value through the Value property. Alternatively, you can use an explicit or implicit cast, you can see an example with the return value below:

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

Or you can even use it when the method just returns T (in this case Person ) by doing a cast. For example, the following code would just like the code above:

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

Combine with Extension

Combine NotNull<T> with an extension method and you can cover even more situations. Here is an example of what the extension method can look like:

 [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; } } 

And here is an example of how it could be used:

 var person = GetPerson().NotNull(); 

GitHub上

For your reference I made the code above available on GitHub, you can find it at:

https://github.com/luisperezphd/NotNull

Related Language Feature

C# 6.0 introduced the "null-conditional operator" that helps with this a little. With this feature, you can reference nested objects and if any one of them is null the whole expression returns null .

This reduces the number of null checks you have to do in some cases. The syntax is to put a question mark before each dot. Take the following code for example:

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

Imagine that country is an object of type Country that has a property called State and so on. If country , State , County , or City is null then address will be null . Therefore you only have to check whether address is null`.

It's a great feature, but it gives you less information. It doesn't make it obvious which of the 4 is null.

Built-in like Nullable?

C# has a nice shorthand for Nullable<T> , you can make something nullable by putting a question mark after the type like so int?

It would be nice if C# had something like the NotNull<T> struct above and had a similar shorthand, maybe the exclamation point (!) so that you could write something like: public void WriteName(Person! person) .

The error line "Object reference not set to an instance of an object. " states that you have not assigned instance object to a object reference and still you are accessing properies/methods of that object.

for example: let say you have a class called myClass and it contains one property prop1.

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

Now you are accessing this prop1 in some other class just like below:

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

above line throws error because reference of class myClass is declared but not instantiated or an instance of object is not assigned to referecne of that class.

To fix this you have to instantiate (assign object to reference of that class).

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

Interestingly, none of the answers on this page mention the two edge cases, hope no one minds if I add them:

Edge case #1: concurrent access to a Dictionary

Generic dictionaries in .NET are not thread-safe and they sometimes might throw a NullReference or even (more frequent) a KeyNotFoundException when you try to access a key from two concurrent threads. The exception is quite misleading in this case.

Edge case #2: unsafe code

If a NullReferenceException is thrown by unsafe code, you might look at your pointer variables, and check them for IntPtr.Zero or something. Which is the same thing ("null pointer exception"), but in unsafe code, variables are often cast to value-types/arrays, etc., and you bang your head against the wall, wondering how a value-type can throw this exception.

(Another reason for non-using unsafe code unless you need it, by the way)

NullReferenceException or Object reference not set to an instance of an object occurs when an object of the class you are trying to use is not instantiated. 例如:

Assume that you have a class named Student.

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

Now, consider another class where you are trying to retrieve the student's full name.

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

As seen in the above code, the statement Student s – only declares the variable of type Student, note that the Student class is not instantiated at this point. Hence, when the statement s.GetFullName() gets executed, it will throw the NullReferenceException.

Well, in simple terms:

You are trying to access an object that isn't created or currently not in memory.

So how to tackle this:

  1. Debug and let the debugger break… It will directly take you to the variable that is broken… Now your task is to simply fix this.. Using the new keyword in the appropriate place.

  2. If it is caused on some database commands because the object isn't present then all you need to do is do a null check and handle it:

     if (i == null) { // Handle this } 
  3. The hardest one .. if the GC collected the object already… This generally occurs if you are trying to find an object using strings… That is, finding it by name of the object then it may happen that the GC might already cleaned it up… This is hard to find and will become quite a problem… A better way to tackle this is do null checks wherever necessary during the development process. 这会为你节省很多时间。

By finding by name I mean some framework allow you to FIndObjects using strings and the code might look like this: FindObject("ObjectName");

If we consider common scenarios where this exception can be thrown, accessing properties withing object at the top.

例如:

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

in here , if address is null , then you will get NullReferenceException.

So, as a practice we should always use null check, before accessing properties in such objects (specially in generic)

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

If one is getting this message during saving or compiling the build, just close all the files and then open any file to compile and save.

For me the reason was that I had rename the file and old file was still open.

It means you are trying to manipulate something which has reference but not yet initialized
The first thing to do here is check every instance created.

Use breakpoints , watches , inspect your varibale values.
Follow stack trace and search for exact row and column which is creating problem

To use methods and member of an object you first have to create that object. If you didn't create it (variable that should hold the object is not initialized), but you try to use it's methods or variables you'll get that error.

Sometime you may just forgot to do initialization.

Edited: new can't return null, but fire's exception when failed. Long time ago it was the case in some languages, but not any more. Thanks @John Saunders for pointing that out.

This is basically is a Null reference exception . As Microsoft states-

A NullReferenceException exception is thrown when you try to access a member of a type whose value is null.

这意味着什么?

That means if any member which doesn't hold any value and we are making that member to perform certain task then the system will undoubtedly toss a message and say-

“Hey wait, that member has no values so it can't perform the task which you are handing it over.”

The exception itself says that something is being referred but whose value is not being set. So this denotes that it only occurs while using reference types as Value types are non-nullable.

NullReferenceException won't occur if we are using Value type members.

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

The above code shows simple string which is assigned with a null value.

Now, when I try to print the length of the string str , I do get An unhandled exception of type 'System.NullReferenceException' occurred message because member str is pointing to null and there can't be any length of null.

' NullReferenceException ' also occurs when we forget to instantiate a reference type.

Suppose I have a class and member method in it. I have not instantiated my class but only named my class. Now if I try to use the method, the compiler will throw an error or issue a warning (depending on the compiler).

 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"); } } 

Compiler for the above code raises an error that variable obj is unassigned which signifies that our variable has null values or nothing. Compiler for the above code raises an error that variable obj is unassigned which signifies that our variable has null values or nothing.

Why it occurs?

  • NullReferenceException arises due to our fault for not checking the object's value. We often leave the object values unchecked in the code development.

  • It also arises when we forget to instantiate our objects. Using methods, properties, collections etc. which can return or set null values can also be the cause of this exception.

How can it be avoided?

There are various ways and methods to avoid this renowned exception:

  1. Explicit Checking: We should adhere to the tradition of checking the objects, properties, methods, arrays, and collections whether they are null. This can be simply implemented using conditional statements like if-else if-else etc.

  2. Exception handling: One of the important ways of managing this exception. Using simple try-catch-finally blocks we can control this exception and also maintain a log of it. This can be very useful when your application is on production stage.

  3. Null operators: Null Coalescing operator and null conditional operators can also be used in handy while setting values to objects, variables, properties and fields.

  4. Debugger: For developers, we have the big weapon of Debugging with us. If have we face NullReferenceException during the development face we can use the debugger to get to the source of the exception.

  5. In-built method: System methods such as GetValueOrDefault(),IsNullOrWhiteSpace() and IsNullorEmpty() checks for nulls and assign the default value if there is a null value.

There are many good answers already here. You can also check more detailed description with examples on my blog .

Hope this helps too!

You are trying to access an object that isn't created or currently not in memory.

When I get this error, I add the following code to any event handler that triggers the error.

 if (!IsLoaded) return; 

The ! means "not", FYI. So if the object in question isn't loaded, the program terminates the execution and prevents the crash.

There is a scenario that can happen that is Class related. The question ended up getting closed prior to my stating the resolution: https://stackoverflow.com/questions/43348009/unable-to-instantiate-class

Beware of classes not instantiating: If any part of your constructor in a class throws a null reference exception the class does not instantiate. In my case it was trying to get a connection string from the web.config that that did not exist.

I instantiated a class:

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

Inside the class itself was a call to get a connection string from the web.config . This part of the constructor threw an null value exception so myClass was null.

If you ever have a situation where a class in not instantiating, try making sure that no part of the class constructor Is throwing a null value exception . F-11 and step through the class and make sure there are no nulls.