簡體   English   中英

使用C#7的foreach聲明中的空合並運算符

[英]Null-coalescing operator in a foreach declaration using C#7

我在C# 7.0中查看這個代碼示例,我不確定引擎蓋下發生了什么以及此循環的性能。

foreach (var c in text ?? throw new ArgumentNullException(nameof(text)))
{
    ...
}

我的問題:

  1. 條件語句是一次還是多次(每次迭代)?
  2. 新語法看起來不同,這樣做有什么好處?

就“foreach如何運作”而言,條件陳述只計算一次。

您可能想要閱讀有關foreach循環如何在這些問題中工作的更多信息:
foreach循環如何在C#中工作?
foreach是否在每次迭代時評估數組?

感謝Svek解釋這是一個新的C#7.0功能,它將在Visual Studio 2017 RC之后發布:
http://structuredsight.com/2016/09/01/c-7-additions-throw-expressions/

我認為“什么是好處”是一種基於意見的問題。
在我看來,它沒有帶來什么好處,只是在術語或代碼可讀性方面是丑陋的。
我建議使用廣泛使用的常見良好做法:

if (text == null) // or string.IsNullOrEmpty for strings
    throw new ArgumentNullException(nameof(text));

foreach (var c in text)
{
    // ...
}

可能,我們將在幾年內看到null-coalescing + throw異常使用,它將成為一個新標准:)

您應該了解foreach內部代碼以了解此C#功能。 foreach語句中表達式的右邊部分必須實現IEnumerable(<T>)接口,整個循環在內部是一個簡單的while ,類似這樣的東西:

// here can be NullReferenceException
var en = text.GetEnumerator();
while(en.MoveNext())
{
    var c = en.Current;
    {
        ...
    }
}

正如您所看到的,此代碼中有一點可以發生NRE ,因此您需要整個循環或Enumerable擴展類 之前檢查枚舉,如下所示:

if (text.IsNullOrWhitespace())
{
    throw new ArgumentNullException(nameof(text));
}

// while loop here or text.SomeLinqCodeHere()

這里有一些代碼行並不是真的沒必要,添加一些沒有實際價值的熵。 在簡單的foreach情況下,它確實是基於意見的關於代碼標准的決定,但是這個功能的真正目的是將它與C#7其他新東西聯系起來,比如?. 運營商 ,像這樣:

int? length = customers?.Length ?? throw new ...;
Customer first = customers?[0] ?? throw new ...;  
int? count = customers?[0]?.Orders?.Count() ?? throw new ...;

在這種情況下拋出異常類似於代碼行末尾的注釋:

int? length = customers?.Length; // should not be null
Customer first = customers?[0]; // should not be null  
int? count = customers?[0]?.Orders?.Count(); // should not be null

但它為您的代碼添加了一些嚴格的類似合同的規則。

至於具有這種表達式的foreach循環的性能,正如已經說過的那樣,它不會受到影響,因為枚舉器只出現一次,並且真正的循環之前

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM