C#代码简化查询:Null容器和Foreach循环

Bri*_*ian 12 c#

我经常有类似这样的代码:

if (itm != null)
{
    foreach (type x in itm.subItems())
    {
        //dostuff
    }
}
//do more stuff
Run Code Online (Sandbox Code Playgroud)

//do more stuff省略的情况下,很容易避免额外的foreach循环.通过使用适当的命令来扩展范围(取决于正在发生的事情,这通常意味着return声明或a continue statement).

这种类型的东西倾向于产生箭头代码.我目前有几种方法可以解决这个问题:

  • 使用像 itm = itm == null ? itm.subItems() : emptyArray
  • 允许箭头代码
  • 使用 goto
  • 使用邪恶的范围黑客(包括整个事物,如果声明在一个范围内,然后突破它).在我看来,邪恶的范围黑客基本上等同于goto丑陋和难以阅读,所以我不认为这是一个有效的解决方案.
  • 将一些块重构为新方法.实际上有一些情况下这可能一个很好的解决方案,但大多数情况下它并不合适,因为空引用主要是来自MS函数的错误条件.

有人关心哪些方法被认为更可取?

Jon*_*eet 15

如果您使用的是C#3,则可以随时编写扩展方法:

public static IEnumerable<SubItem> SafeSubItems(this ItemType item)
{
     return item == null ? Enumerable.Empty<SubItem> : source.SubItems();
}
Run Code Online (Sandbox Code Playgroud)

然后写下:

foreach (SubItem x in itm.SafeSubItems())
{
    // do stuff
}
// do more stuff
Run Code Online (Sandbox Code Playgroud)

关键是扩展方法甚至可以调用"on"null引用.

什么是好的将是一个"null-safe dereferencing"运算符,所以我们可以写:

// Not valid C# code!
foreach (SubItem x in itm?.SubItems() ?? Enumerable.Empty<SubItem>())
{
}
Run Code Online (Sandbox Code Playgroud)

或者只是定义一个EmptyIfNull扩展方法IEnumerable<T>并使用

// Not valid C# code!
foreach (SubItem x in (itm?.SubItems()).EmptyIfNull())
{
}
Run Code Online (Sandbox Code Playgroud)