阅读了很多关于Null propagation operator ?.
的内容,我没有回答是否在以下情况中有用。
抛出的代码:
int[] values = null;
foreach ( var i in values ) // Throws since values is null.
{
// ...
}
为了实现这一点,我必须在访问null
变量之前添加values
检查。
上述代码很可能超出了Null传播运算符的设计考虑范围。不过,可以肯定的是,我不得不问。
我的问题:
在尝试访问null
循环中的foreach
个集合时,Null传播运算符是否有用?
答案 0 :(得分:10)
我找到了另一种工作方式:
当使用Jon Skeet(等人)精彩的MoreLinq扩展时,我可以在我的初始示例中使用ForEach
extension method,如:
int[] values = null;
values?.ForEach(i=> /*...*/); // Does not throw, even values is null.
答案 1 :(得分:8)
不,不是。它旨在以安全的方式允许对象的访问成员。在这种情况下,您必须检查数组是否为 null 。
答案 2 :(得分:4)
你会如何使用它?
您提供的代码:
int[] values = null;
foreach (var i in values)
{
// ...
}
enxpands into something:
int[] values = null;
var enumerator = values.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
var i = enumerator.Current;
// ...
}
}
finally
{
var disposable = enumerator as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
我想你可以这样写:
int[] values = null;
foreach (var i in values?.)
{
// ...
}
编译器必须将其扩展为以下内容:
int[] values = null;
var enumerator = values?.GetEnumerator();
try
{
while (enumerator?.MoveNext() ?? false)
{
var i = enumerator.Current;
// ...
}
}
finally
{
var disposable = enumerator as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
请记住:
a = b?.M();
扩展为:
a = b == null ? null : b.M();
如果您不想明确写出if
语句,您可以始终依赖好的null-coalescing operator (??):
int[] values = null;
foreach (var i in values ?? Enumerable.Empty<int>())
{
// ...
}
答案 3 :(得分:1)
对于List<T>
,您可以使用list?.ForEach(i => ...);
,对于其他枚举,您可以像这样制作自己的ForEach扩展程序:
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
if (source == null) { return; }
foreach (T item in source) {
action(item);
}
}
您可以这样称呼它:myPossiblyNullEnumerable.ForEach(i => ...);
如果你希望你的ForEach扩展在调用null枚举时抛出,你可以离开null检查,并使用与List的版本相同的elvis语法来调用它:myPossiblyNullEnumerable?.ForEach(i => ...);