BCLチームのメンバーだけが確実に教えてくれList<T>.ForEach
ますが、リストを変更できるのはおそらく単なる見落としでした。
まず、DavidBの答えは私には意味がありません。ループList<T>
内でリストを変更するかどうかをチェックし、変更する場合はスローするのは、C#ではありません。使用している言語とは何の関係もありません。foreach
InvalidOperationException
次に、ドキュメントに次の警告があります。
Action <T>デリゲートの本体で基になるコレクションを変更することはサポートされておらず、未定義の動作を引き起こします。
ForEach
BCLチームが、未定義の動作をするような単純な方法を望んでいた可能性は低いと思います。
第3に、.NET 4.5以降、デリゲートがリストを変更した場合はList<T>.ForEach
をスローします。InvalidOperationException
プログラムが古い動作に依存している場合、ターゲットの.NET 4.5に再コンパイルすると、プログラムは動作を停止します。マイクロソフトがこの重大な変更を喜んで受け入れるという事実は、元の動作が意図されておらず、信頼されるべきではないことを強く示唆しています。
List<T>.ForEach
参考までに、リファレンスソースから直接.NET4.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]);
}
}
そして、これが.NET4.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);
}