[英]Null-coalescing operator in a foreach declaration using C#7
我在C# 7.0
中查看這個代碼示例,我不確定引擎蓋下發生了什么以及此循環的性能。
foreach (var c in text ?? throw new ArgumentNullException(nameof(text)))
{
...
}
我的問題:
就“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.