gpt4 book ai didi

c# - 为什么 List.ForEach() 实现 for 循环?

转载 作者:可可西里 更新时间:2023-11-01 08:23:26 25 4
gpt4 key购买 nike

我不明白为什么 List<T>.ForEach()扩展方法实现了一个 for在引擎盖下循环。这打开了修改集合的可能性。正常 foreach在这种情况下肯定会抛出异常 ForEach()应该以同样的方式使用react吗?

如果您出于任何原因必须改变一个集合,那么您肯定应该手动迭代 for 中的集合循环?

foreach 之间似乎有一点语义上的矛盾。和 List<T>.ForEach() .

我错过了什么吗?

最佳答案

只有 BCL 团队的一名成员可以肯定地告诉我们,但这可能只是一个疏忽 List<T>.ForEach允许您修改列表。

首先,David B 的回答对我来说没有意义。这是List<T> ,而不是 C#,它会检查您是否修改了 foreach 中的列表循环并抛出 InvalidOperationException如果你这样做。这与您使用的语言无关。

其次,documentation 中有这个警告:

Modifying the underlying collection in the body of the Action<T> delegate is not supported and causes undefined behavior.

我发现 BCL 团队不太可能想要像 ForEach 这样简单的方法有未定义的行为。

第三,从 .NET 4.5 开始,List<T>.ForEach 抛出 InvalidOperationException如果代表修改列表。如果程序依赖于旧行为,it will stop working当它被重新编译为目标 .NET 4.5 时。 Microsoft 愿意接受这一重大更改这一事实强烈表明原始行为是无意的,不应依赖。

作为引用,这里是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);
}

关于c# - 为什么 List<T>.ForEach() 实现 for 循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11493330/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com