【问题标题】:Why is my list (from .Where) updating its elements by itself?为什么我的列表(来自 .Where)会自行更新其元素?
【发布时间】:2019-09-14 12:39:53
【问题描述】:

我正在为一个游戏编写一个机器人,其中几个玩家有不同的动作并使用它们相互交互。

我正在编写的其中一个动作选择 2 个玩家(A 和 B),并让所有其他以 A 为目标的玩家都以 B 为目标,反之亦然。

但是,使用我的代码,只有以 B 为目标的玩家才会交换目标。如果玩家最初以 A 为目标,我的代码会将其更改为 B,然后再将其更改为 A。

var target1 = Players.FirstOrDefault(x => x.Id == doorman.Choice);
var target2 = Players.FirstOrDefault(x => x.Id == doorman.Choice2);

if (target1 != null && target2 != null)
{
    var going1 = Players.Where(x => x.Choice == target1.Id && x.Id != doorman.Id);
    var going2 = Players.Where(x => x.Choice == target2.Id && x.Id != doorman.Id);

    foreach (var visitor in going1)
        visitor.Choice = target2.Id;

    foreach (var visitor in going2)
        visitor.Choice = target1.Id;
}

我认为问题在于列表going2 即使在被声明后也会更新,并且将going1 中的所有玩家都添加到其中。

这意味着所有以target1为目标的玩家都被交换到target2,然后又回到target1

如何让我的going1going2 列表在声明后不自行更新?

【问题讨论】:

  • 您可能希望使用.ToList() 语句强制评估您的Where() 调用。
  • 您可能想查找“延迟执行”一词,并可能查看stackoverflow.com/q/7324033/11683stackoverflow.com/q/47379362/11683
  • lists going1going2 以及列表 Players 引用相同的源,因此其中任何一个的任何更改都将反映在所有这些中(就像您在两个 foreach 循环中所做的那样)。您已将 going1going2 声明为新列表,但它们仅引用源!
  • 如果您不想更改原件,则需要克隆原件。

标签: c#


【解决方案1】:

你应该在Where之后使用.ToList()

var going1 = Players.Where(x => x.Choice == target1.Id && x.Id != doorman.Id).ToList();
var going2 = Players.Where(x => x.Choice == target2.Id && x.Id != doorman.Id).ToList();

由于 Linq .Where 将返回 Enumerable 列表,当您尝试访问 going1going2 内的 foreach 对象时,它将再次被评估。但是如果你使用.ToList(),那么它会立即评估值并将其分配给going1going2对象。

【讨论】:

    猜你喜欢
    • 2019-08-13
    • 2023-01-04
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多