簡體   English   中英

為什么列表 <T> .ForEach()實現for循環?

[英]Why does List<T>.ForEach() implement a for loop?

我不明白為什么List<T>.ForEach()擴展方法實現了一個for循環。 這開辟了收集被修改的可能性。 正常的foreach會在這種情況下拋出異常,所以ForEach()肯定會以同樣的方式做出反應嗎?

如果你因為某種原因必須改變一個集合,那么你肯定應該在for循環中手動迭代集合嗎?

foreachList<T>.ForEach()之間似乎存在一些語義矛盾。

我錯過了什么嗎?

因為List.ForEach遵循MSDN的定義:

對List的每個元素執行指定的操作。

這意味着對元素執行的Action可能會更改元素或集合本身 在這種情況下,沒有其他方法(如果沒有創建costy克隆集合, 如果可能的話)支付這個,然后使用簡單的for

如果在foreach迭代期間更改集合,它自然會引發異常。

foreach是一個C#語言元素。 它遵循C#的規則。

List<T>.ForEach是一種.NET Framework方法。 它遵循.NET的規則,其中foreach不存在。

這是“語言與框架”混淆的一個例子。 框架方法必須以多種語言工作,並且語言(通常)具有矛盾的語義。

這種“語言與框架”混淆的另一個例子是.net 3和.NET 3.5之間對Enumerable.Cast的重大改變。 在.NET 3中, Cast使用了C#語義。 在.net 3.5中,它被改為使用.net語義。

只有BCL團隊的成員可以肯定地告訴我們,但這可能僅僅是List<T>.ForEach的疏忽List<T>.ForEach允許您修改列表。

首先,David B的答案對我來說沒有意義。 它是List<T> ,而不是C#,它檢查你是否修改了foreach循環中的列表,如果你這樣做則拋出InvalidOperationException 它與您正在使用的語言無關。

其次, 文檔中有這個警告:

不支持修改Action <T>委托正文中的基礎集合,並導致未定義的行為。

我發現BCL團隊不太可能希望像ForEach這樣的簡單方法具有未定義的行為。

第三,從.NET 4.5開始, List<T>.ForEach 在委托修改列表時拋出InvalidOperationException 如果程序依賴於舊的行為, 它將在重新編譯為目標.NET 4.5時停止工作 微軟願意接受這一突破性變化的事實強烈表明,原始行為是無意的,不應該依賴。

作為參考,這里是List<T>.ForEach如何在.NET 4.0中實現,直接來自參考源:

public void ForEach(Action<T> action) {
    if( action == null) {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    Contract.EndContractBlock();

    for(int i = 0 ; i < _size; i++) {
        action(_items[i]);
    }
}

以下是.NET 4.5中的更改方式:

public void ForEach(Action<T> action) {
    if( action == null) {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    Contract.EndContractBlock();

    int version = _version;

    for(int i = 0 ; i < _size; i++) {
        if (version != _version && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) {
            break;
        }
        action(_items[i]);
    }

    if (version != _version && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
        ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}

暫無
暫無

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

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