问题描述
据我了解,C#的foreach迭代变量是不可变的。
As I understand it, C#'s foreach iteration variable is immutable.
这意味着我不能修改这样的迭代器:
Which means I can't modify the iterator like this:
foreach (Position Location in Map)
{
//We want to fudge the position to hide the exact coordinates
Location = Location + Random(); //Compiler Error
Plot(Location);
}
我不能直接修改迭代变量,而是,我必须用一个for循环
I can't modify the iterator variable directly and instead, I have to use a for loop
for (int i = 0; i < Map.Count; i++)
{
Position Location = Map[i];
Location = Location + Random();
Plot(Location);
i = Location;
}
这是一个C ++背景的,我看到的foreach作为替代for循环。但与上述限制,我通常回退到使用的for循环。
Coming from a C++ background, I see foreach as an alternative to the for loop. But with the above restriction, I usually fallback to using the for loop.
我很好奇,是什么使得后面的迭代器不可变的理由?
I'm curious, what is the rationale behind making the iterator immutable?
编辑:
此问题更是一个好奇的问题,而不是作为编码问题。我AP preciated编码的答案,但我不能将它们标记为答案。
This question is more of a curiousity question and not as a coding question. I appreciated the coding answers but I can't mark them as answers.
另外,上面的例子是过于简单化。这里是什么,我想做一个C ++的例子:
Also, the example above was over-simplified. Here is a C++ example of what I want to do:
// The game's rules:
// - The "Laser Of Death (tm)" moves around the game board from the
// start area (index 0) until the end area (index BoardSize)
// - If the Laser hits a teleporter, destroy that teleporter on the
// board and move the Laser to the square where the teleporter
// points to
// - If the Laser hits a player, deal 15 damage and stop the laser.
for (int i = 0; i < BoardSize; i++)
{
if (GetItem(Board[i]) == Teleporter)
{
TeleportSquare = GetTeleportSquare(Board[i]);
SetItem(Board[i], FreeSpace);
i = TeleportSquare;
}
if (GetItem(Board[i]) == Player)
{
Player.Life -= 15;
break;
}
}
我做不到上面的C#的foreach,因为我的迭代器是不可变的。我认为(纠正我,如果我错了),这是特定的foreach的语言设计的。
I can't do the above in C#'s foreach because the iterator i is immutable. I think (correct me if I'm wrong), this is specific to the design of foreach in languages.
我感兴趣的是,为什么在foreach迭代器是不可变的。
I'm interested in why the foreach iterator is immutable.
推荐答案
让我们用愚蠢,但说明性的例子开始了:
Lets start out with a silly but illustrative example:
Object o = 15;
o = "apples";
在任何时候做我们得到的IM pression我们刚满15号到苹果的字符串。我们知道, 0
只是一个指针。现在,让我们在迭代器的形式做到这一点。
At no point do we get the impression that we just turned the number 15 into a string of apples. We know that o
is simply a pointer. Now lets do this in iterator form.
int[] nums = { 15, 16, 17 };
foreach (Object o in nums) {
o = "apples";
}
此外,这真的无所作为。或者至少它的将会的一事无成了编译它。这当然不会插入我们的字符串插入int数组 - ,这是不允许的,我们知道, 0
只是一个指针,反正
Again, this really accomplishes nothing. Or at least it would accomplish nothing were it to compile. It certainly wouldn't insert our string into the int array -- that's not allowed, and we know that o
is just a pointer anyway.
让我们把你的例子:
foreach (Position Location in Map)
{
//We want to fudge the position to hide the exact coordinates
Location = Location + Random(); //Compiler Error
Plot(Location);
}
被这个编译时,位置
在您的示例明星出指的是值地图
,但随后你改变它来指一个新的位置
(由加法运算符隐式创建)。功能上它等同于本(它编译):
Were this to compile, the Location
in your example stars out referring to a value in Map
, but then you change it to refer to a new Position
(implicitly created by the addition operator). Functionally it's equivalent to this (which DOES compile):
foreach (Position Location in Map)
{
//We want to fudge the position to hide the exact coordinates
Position Location2 = Location + Random(); //No more Error
Plot(Location2);
}
那么,为什么微软禁止您重新分配用于迭代指针?清晰度一件事 - 你不希望人们赋予它思想,他们已经改变了循环中的地位。易于实现的另一个:变量可能会隐藏一些内部逻辑表明正在进行循环的状态。
So, why does Microsoft prohibit you from re-assigning the pointer used for iteration? Clarity for one thing -- you don't want people assigning to it thinking they've changed your position within the loop. Ease of implementation for another: The variable might hide some internal logic indicating the state of the loop in progress.
但更重要的是,没有任何理由让你的需要的分配给它。它重新presents循环序列的当前元素。值分配给它打破了单一职责原则或如果你遵循编码恐怖。变量应该是说只有一件事。
But more importantly, there is no reason for you to want to assign to it. It represents the current element of the looping sequence. Assigning a value to it breaks the "Single Responsibility Principle" or Curly's Law if you follow Coding Horror. A variable should mean one thing only.
这篇关于为什么在C#foreach语句迭代变量只读?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!