在许多情况下,都会收到 a ,NullReferenceException
这是引发最多问题的例外之一。这是什么意思NullReferenceException
,如何解决?
对于NullReferenceException
VB.NET,请参阅NullReferenceException:它是什么以及如何修复它?
在许多情况下,都会收到 a ,NullReferenceException
这是引发最多问题的例外之一。这是什么意思NullReferenceException
,如何解决?
对于NullReferenceException
VB.NET,请参阅NullReferenceException:它是什么以及如何修复它?
原因是什么?
本质上
您正在尝试使用某个
null
(或Nothing
在 VB.NET 中)的对象。这意味着您要么已将其初始化为null
,要么您从未对其进行过初始化。null
是与其他值一样的值,并以相同的方式传递。如果您有null
方法“A”,则可能是方法“B”已将一个传递null
给方法“A”。这个答案的其余部分将更详细地介绍并显示许多程序员犯的常见错误,这些错误可能导致
NullReferenceException
.进一步来说
当运行时启动一个时
NullReferenceException
,它总是意味着同一件事:您正在尝试使用引用。此引用尚未初始化(或在某个时间点已初始化,但不再初始化)。这意味着引用是
null
,如果引用是 ,则不能访问引用的成员null
。这是最简单的情况:此代码将在第二行抛出一个
NullReferenceException
,因为无法在指向ToUpper()
的引用上调用实例方法。string
null
净化
如何找到异常的来源
NullReferenceException
?除了研究将在发生的确切位置抛出的异常本身之外,还应应用 Visual Studio 中的一般调试规则:策略性地设置断点并检查变量,方法是将光标放在它们的名称上,通过打开(快速)观察窗口,或使用现有的调试面板,如本地和自动。如果您想查找引用分配或未分配的位置,请右键单击其名称并选择“查找所有引用”。然后,您可以在所有找到的位置上放置一个断点并在调试中再次运行该程序。每次调试器在该点停止执行时,您都需要通过检查变量并验证它是否应指向实例来确定您是否期望该点的引用为非空。
通过这种方式遵循程序的流程,您将能够找到实例不应该为空的位置,以及为什么它没有按应有的方式初始化。
例子
我们可能会遇到此异常的一些常见场景:
通用的
如果 ref1 或 ref2 或 ref3 是
null
,那么你会得到一个NullReferenceException
. 如果你想解决这个问题,那么你需要通过null
将表达式重写为最简单的等价物来找出它是哪一个:例如,在 中
HttpContext.Current.User.Identity.Name
,HttpContext.Current
可能是null
,或者属性User
可能是null
,或者属性Identity
可能是null
。类实例
创建任何引用类型(类)变量时,默认情况下将其初始化为
null
.类变量必须初始化或分配给已初始化的同一类的实例。初始化是使用关键字来实现的
new
。暗示
如果要避免子(Person)的空引用,可以在父(Book)的构造函数中对其进行初始化。
这同样适用于嵌套对象初始化器:
虽然在这个例子中使用了关键字
new
,但它只创建了一个新的实例Libro
,而不是一个新的实例Persona
,所以属性Autor
仍然存在null
。数组
数组的元素
不规则数组(锯齿状数组)
集合/列表/字典
范围变量(间接/延迟)
事件
不符合约定的名称:
如果您对字段的命名与局部变量不同,您可能已经注意到您从未初始化过该字段。
这可以通过遵循字段
_
在名称前添加下划线 ( ) 的约定来解决:ASP.NET 页面的生命周期:
ASP.NET 会话值
ASP.NET MVC 空视图模型
如果在 ASP.NET MVC 视图中引用某个属性时发生异常
@Modelo
,您需要了解Modelo
在您的方法中初始化该属性action
,当您返回(return
)一个视图时。当您从控制器返回一个空模型(或模型属性)时,视图访问它时会引发异常:WPF中控件和事件的创建顺序
WPF 控件是在调用期间
InitializeComponent
按照它们在可视树中出现的顺序创建的。NullReferenceException
如果之前使用事件处理程序等创建的控件可能会引发异常。, 期间触发InitializeComponent
, 参考之后创建的控件。例如:
这里
comboBox1
是之前创建的label1
。如果事件comboBox1_SelectionChanged
试图引用label1
,它还没有被创建。更改 XAML 中声明的顺序(例如,放在
label1
前面comboBox1
,忽略设计理念问题),至少可以解决NullReferenceException
这种情况。铸造与
as
这不会抛出 InvalidCastException,但会在强制转换
null
失败时(以及unObjeto
null 时)返回。所以你必须小心它。LINQ FirstOrDefault() 和 SingleOrDefault()
简单版本
First()
并Single()
在没有任何内容时抛出异常。在这种情况下,版本"OrDefault"
返回 null。你必须意识到这一点。前锋
foreach
当您尝试遍历空集合时抛出异常。这通常是由返回集合的方法的意外空结果引起的。一个更现实的例子 - 从 XML 文档中选择节点。如果未找到节点但初始调试显示所有属性均有效,则会引发异常:
避免它的方法
显式检查
null
并忽略空值。null
如果您预计引用可能永远为空,您可以在访问实例成员之前询问它是否为空:显式检查
null
并返回默认值。对您期望返回实例的方法的调用可能会返回
null
,例如,当未找到正在搜索的对象时。在这些情况下,您可以选择返回默认值:显式检查
null
并抛出自定义异常。您还可以抛出自定义异常,以便在调用该方法的代码中捕获它:
使用
Debug.Assert
if value should never benull
,在抛出异常之前捕获问题。当您在开发阶段知道一个方法可能会返回
null
,即使这种情况永远不会发生,您可以使用Debug.Assert()
它在它发生时尽快停止程序流:此检查不会在您的Release Build上执行,导致它在运行时
NullReferenceException
再次发布。libro == null
GetValueOrDefault()
在“可空”值类型 ( nullables ) 中使用以在它们为空时获取默认值。使用空合并运算符:
??
[C#] 或If()
[VB]。遇到 null 时提供默认值的最短方法:
使用 null 条件运算符:(
?.
在 C# 6 和 VB.NET 14 中可用):这个算子也被称为安全导航或猫王(因为它的形状)。如果运算符左侧的表达式是
null
,则不计算运算符的右侧,而是返回 ,null
。在这种情况下:如果此人没有头衔,则此代码将引发异常,因为它试图调用
ToUpper
具有空值的属性。在 C# 5 及更低版本中,可以这样修复:
现在该变量
titulo
将不会null
引发异常。C# 6 引入了一个更短的语法来做同样的事情:El resultado de esto es que a la variable
titulo
se le asignará null, y la llamada aToUpper
nunca se realizará sipersona.Titulo
esnull
.Por supuesto, todavía tienes que comprobar que
title
no seanull
o usar el operador de condición nula junto al operador de comprobación de valores nulos (??
) para proporcionar un valor por defecto:Esta respuesta es una traducción de la magnifica respuesta que se encuentra en la versión en inglés de Stack Overflow
En mi caso tenia un List inicializado en null
Cambie la inicializacion por el tipo de objeto y se resolvió