C# 空传播算子与foreach
在阅读了大量关于的文章后,我没有发现答案:在下面的场景中,它是否有用 抛出的代码:C# 空传播算子与foreach,c#,null,c#-6.0,null-propagation-operator,C#,Null,C# 6.0,Null Propagation Operator,在阅读了大量关于的文章后,我没有发现答案:在下面的场景中,它是否有用 抛出的代码: int[] values = null; foreach ( var i in values ) // Throws since values is null. { // ... } 要使其工作,我必须在访问值变量之前添加一个null检查 上述代码很可能超出了空传播运算符的设计考虑范围。当然,我还是要问 我的问题: 尝试访问foreach循环中的Null集合时,Null传播运算符是否有用?否否。它的设
int[] values = null;
foreach ( var i in values ) // Throws since values is null.
{
// ...
}
要使其工作,我必须在访问值
变量之前添加一个null
检查
上述代码很可能超出了空传播运算符的设计考虑范围。当然,我还是要问
我的问题:
尝试访问
foreach
循环中的Null
集合时,Null传播运算符是否有用?否否。它的设计允许以安全的方式访问对象的成员。在这种情况下,您必须检查数组是否为空。您将如何使用它
您提供的代码:
int[] values = null;
foreach (var i in values)
{
// ...
}
扩展成某物:
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();
}
}
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
if (source == null) { return; }
foreach (T item in source) {
action(item);
}
}
编译器必须将其扩展为以下内容:
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();
}
}
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
if (source == null) { return; }
foreach (T item in source) {
action(item);
}
}
并牢记:
a = b?.M();
扩展为:
a = b == null ? null : b.M();
如果您不想显式地编写If
语句,您可以始终依赖于旧的:
int[]值=null;
foreach(值中的变量i??可枚举的.Empty())
{
// ...
}
我找到了另一种工作方式:
当使用Jon Skeet(等人)的奇妙扩展时,我可以在我的初始示例中使用如下:
int[] values = null;
values?.ForEach(i=> /*...*/); // Does not throw, even values is null.
对于List
您可以使用List?.ForEach(i=>…)对于其他可枚举项,您可以像这样创建自己的ForEach扩展:
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();
}
}
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
if (source == null) { return; }
foreach (T item in source) {
action(item);
}
}
publicstaticvoidforeach(此IEnumerable源代码,Action){
如果(source==null){return;}
foreach(源中的T项){
行动(项目);
}
}
您这样称呼它:myPossiblyNullEnumerable.ForEach(i=>…)代码>
如果希望ForEach扩展在调用null可枚举项时抛出,只需保留null检查,并使用与列表版本相同的elvis语法调用它:myPossiblyNullEnumerable?.ForEach(i=>…)
不是答案,但您可以编写foreach(值中的VARI??Enumerable.Empty())
以避免嵌套。或者使用ArrayList或List:)@Boctulus这些也是可为空的引用类型,您知道吗@Boctulus也看到了这个Roslyn问题:在System.Collections.Generic
中有一个ForEach
扩展。没有必要再使用MoreLinq了。它还可以在不引发异常的情况下处理null传播。