扩展方法的空引用异常
Null Reference Exception from extension method
我有一个名为 ParseItemsToIntegers
的扩展方法,它是一个字符串数组的扩展方法,我像使用任何扩展一样使用它。
var ids = ChkBoxSelected.ParseItemsToIntegers();
我观察到的行为是,如果 ChkBoxSelected
为 null,它将毫无问题地调用扩展方法,但随后在扩展方法中它会在 null 字符串上抛出空引用异常数组。
它是如何解析 null 上的扩展方法的?
为什么调用扩展方法时ChkBoxSelected
没有抛出空引用异常?
它不会抛出 NRE,因为扩展方法不是实例方法,无论它们看起来多少是实例方法。正如您在定义方法时明确指出的那样,它实际上是一个静态方法。当您将 null
值作为第一个参数传递给静态方法时,不会抛出 NRE,它只是传入一个 null
值,并且该静态方法可以用它做任何它想做的事。
调用扩展方法 ChkBoxSelected.ParseItemsToIntegers()
等同于使用常规静态方法语法调用它 ParseItemsToIntegers(ChkBoxSelected)
。 ChkBoxSelected
的类型在编译时是已知的,因此编译器可以解析该方法。
NullReferenceException
被抛入它试图使用 ChkBoxSelected
的方法中。
调用实例方法时,NullReferenceException
会立即抛出,因为CLR会检查对象的实际类型以选择正确的多态调用(即使是非虚拟方法也是这样调用的)。
扩展方法只是更明确的 static
方法调用的语法糖。
所以您的代码可能看起来是(实际上不是)
null.ParseItemsToIntegers();
真的被称为
StaticClass.ParseItemsToIntegers(null);
null 引用只是一个参数,它完全可以接受 null 作为值(因为它是引用类型的合法值)。在您的实际方法中的某处,它可能期望一个非空数组,然后抛出一个 NPE。
我有一个名为 ParseItemsToIntegers
的扩展方法,它是一个字符串数组的扩展方法,我像使用任何扩展一样使用它。
var ids = ChkBoxSelected.ParseItemsToIntegers();
我观察到的行为是,如果 ChkBoxSelected
为 null,它将毫无问题地调用扩展方法,但随后在扩展方法中它会在 null 字符串上抛出空引用异常数组。
它是如何解析 null 上的扩展方法的?
为什么调用扩展方法时ChkBoxSelected
没有抛出空引用异常?
它不会抛出 NRE,因为扩展方法不是实例方法,无论它们看起来多少是实例方法。正如您在定义方法时明确指出的那样,它实际上是一个静态方法。当您将 null
值作为第一个参数传递给静态方法时,不会抛出 NRE,它只是传入一个 null
值,并且该静态方法可以用它做任何它想做的事。
调用扩展方法 ChkBoxSelected.ParseItemsToIntegers()
等同于使用常规静态方法语法调用它 ParseItemsToIntegers(ChkBoxSelected)
。 ChkBoxSelected
的类型在编译时是已知的,因此编译器可以解析该方法。
NullReferenceException
被抛入它试图使用 ChkBoxSelected
的方法中。
调用实例方法时,NullReferenceException
会立即抛出,因为CLR会检查对象的实际类型以选择正确的多态调用(即使是非虚拟方法也是这样调用的)。
扩展方法只是更明确的 static
方法调用的语法糖。
所以您的代码可能看起来是(实际上不是)
null.ParseItemsToIntegers();
真的被称为
StaticClass.ParseItemsToIntegers(null);
null 引用只是一个参数,它完全可以接受 null 作为值(因为它是引用类型的合法值)。在您的实际方法中的某处,它可能期望一个非空数组,然后抛出一个 NPE。