在这里讨论了SO之后,我已经多次读过可变结构是"邪恶"的评论(就像这个问题的答案一样).
C#中可变性和结构的实际问题是什么?
我知道值类型应该是不可变的,但这只是一个建议,而不是一个规则,对吧?那么为什么我不能做这样的事情:
struct MyStruct
{
public string Name { get; set; }
}
public class Program
{
static void Main(string[] args)
{
MyStruct[] array = new MyStruct[] { new MyStruct { Name = "1" }, new MyStruct { Name = "2" } };
foreach (var item in array)
{
item.Name = "3";
}
//for (int i = 0; i < array.Length; i++)
//{
// array[i].Name = "3";
//}
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
代码中的foreach循环不会编译,而注释for循环工作正常.错误消息:
无法修改'item'的成员,因为它是'foreach迭代变量'
这是为什么?
据我了解,C#的foreach迭代变量是不可变的.
这意味着我不能像这样修改迭代器:
foreach (Position Location in Map)
{
//We want to fudge the position to hide the exact coordinates
Location = Location + Random(); //Compiler Error
Plot(Location);
}
Run Code Online (Sandbox Code Playgroud)
我无法直接修改迭代器变量,而是必须使用for循环
for (int i = 0; i < Map.Count; i++)
{
Position Location = Map[i];
Location = Location + Random();
Plot(Location);
i = Location;
}
Run Code Online (Sandbox Code Playgroud)
来自C++背景,我认为foreach是for循环的替代品.但是由于上述限制,我通常会回退使用for循环.
我很好奇,使迭代器不可变的原理是什么?
编辑:
这个问题更多的是一个好奇的问题,而不是一个编码问题.我很欣赏编码答案,但我不能将它们标记为答案.
此外,上面的例子过于简化了.这是我想要做的C++示例:
// The game's rules:
// - The "Laser Of Death (tm)" moves around the game board from the
// start area (index …Run Code Online (Sandbox Code Playgroud) 我有这个代码(C#):
using System.Collections.Generic;
namespace ConsoleApplication1
{
public struct Thing
{
public string Name;
}
class Program
{
static void Main(string[] args)
{
List<Thing> things = new List<Thing>();
foreach (Thing t in things) // for each file
{
t.Name = "xxx";
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
它不会编译.
错误是:
Cannot modify members of 't' because it is a 'foreach iteration variable'
Run Code Online (Sandbox Code Playgroud)
但是,如果我Thing改为a class而不是a struct,它会编译.
请有人解释一下发生了什么?