我有一个空检查扩展方法
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。 为什么?
这种行为不会使任何空检查扩展方法的使用变得非常危险吗?
我认为您对可为空引用类型和可为空值类型感到困惑。
可空引用类型就是这种类型。由于
object
是引用类型,因此您只有一个对象。如果取消引用空引用类型,则会出现异常。如果您知道 object
在运行时不为 null,则可以使用以下语法覆盖编译器 ...
对象!.intArray
例如。但是,你为什么要这么做呢?显然,在您的情况下,对象为空。就检查一下吧。
如果由于短路而导致
object
为 null
,则永远不会调用您的扩展方法,即,如果 object?.intArray.OrEmptyIfNull()
为 null
,则表达式 object
始终为 null
。在这种情况下甚至没有评估intArray
。
更简洁的方法是在尝试迭代之前实际检查引用:
if (object?.intArray != null)
foreach (int i in object.intArray)
...