C# 子对象上的 null 检查扩展方法不起作用

问题描述 投票:0回答:2

我有一个空检查扩展方法

public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();
}

在运行循环之前调用它可以避免额外的空检查,就像这样

int[] intArray = new int[] { 1, 2, 3 };
int sum = 0;
foreach (int i in intArray.OrEmptyIfNull())
    sum += i;

但是,如果我使用的 IEnumerable 在另一个对象内部,如果周围的对象为 null,它将失败并出现 NullReferenceException - 就像这里一样

foreach (int i in object?.intArray.OrEmptyIfNull())
    sum += i;

阅读完在 C# 中的讨论后,当您在 null 对象上调用扩展方法时会发生什么?我了解编译器会将表达式转换为

ExtensionClass.OrEmptyIfNull(object?.intArray)

但是如果 object == null,我在这里遇到 NullReferenceException。 为什么?

这种行为不会使任何空检查扩展方法的使用变得非常危险吗?

c# extension-methods nullreferenceexception
2个回答
0
投票

我认为您对可为空引用类型和可为空值类型感到困惑。

可空引用类型就是这种类型。由于

object
是引用类型,因此您只有一个对象。如果取消引用空引用类型,则会出现异常。如果您知道
object
在运行时不为 null,则可以使用以下语法覆盖编译器 ...

对象!.intArray

例如。但是,你为什么要这么做呢?显然,在您的情况下,对象为空。就检查一下吧。


0
投票

如果由于短路而导致

object
null
,则永远不会调用您的扩展方法,即,如果
object?.intArray.OrEmptyIfNull()
null
,则表达式
object
始终为
null
。在这种情况下甚至没有评估
intArray

更简洁的方法是在尝试迭代之前实际检查引用:

if (object?.intArray != null)
    foreach (int i in object.intArray)
        ...
© www.soinside.com 2019 - 2024. All rights reserved.