gpt4 book ai didi

c# - 修改 IEnumerable foreach 与 List.ForEach 中的结构

转载 作者:太空宇宙 更新时间:2023-11-03 18:35:53 25 4
gpt4 key购买 nike

这个问题专门针对结构。

假设我定义:

struct Complex
{
public double real, imaginary;
}

如果我尝试:

var numbers = new[] 
{
new Complex() { real = 1, imaginary = 1 },
new Complex() { real = -1, imaginary = -1 }
};

foreach ( var z in numbers )
{
z.real += 1;
}

我收到编译错误:错误:无法修改“complex”的成员,因为它是“foreach 迭代变量”

但是,

var numbers = new List<Complex>();
numbers.Add( new Complex() { real = 1, imaginary = 1 } );
numbers.Add( new Complex() { real = -1, imaginary = -1 } );

numbers.ForEach( z => z.real += 1 );

编译没有错误。牢记'foreach'编译错误,有什么理由不在这里给出编译时错误吗?

最佳答案

长话短说:

  • C# 尝试保护您免受您自己的伤害
  • 如果你足够努力,你就可以做坏事 - 语言并不能保护你免受你可能做的所有蠢事
  • 可变结构不好

Is there any reason for not giving a compile-time error here then?

是的。您只是修改一个参数,这绝对没问题。参数不被视为只读,而 foreach 循环中的迭代变量被视为只读。来自 C# 5 规范的第 8.8.4 节:

During execution of a foreach statement, the iteration variable represents the collection element for which an iteration is currently being performed. A compile-time error occurs if the embedded statement attempts to modify the iteration variable (via assignment or the ++ and -- operators) or pass the iteration variable as a ref or out parameter.

这并不意味着使用可变变量是个好主意 - 也不意味着您的 ForEach 循环会执行您想要的操作。 (毕竟参数按值传递给了委托(delegate)。)

如果你真的想在 foreach 版本中做类似的事情(同样无效,但是嘿......),只需在结构中编写一个方法来改变字段,然后从循环中调用它。这是完全正确的...

// Bad code! Valid, but horrible
foreach (var z in numbers)
{
z.SetReal(z.real + 1);
}

它仍然不会修改列表中的值...但它不会在编译时失败。

关于c# - 修改 IEnumerable foreach 与 List<T>.ForEach 中的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15554331/

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