使用Linq过滤IEnumerable

时间:2016-01-17 15:17:46

标签: c# linq

我有一个玩家列表,我想只取出有效的玩家并将它们放入另一个IEnumerable

我就是这样做的:

private IEnumerable<Objects.Player> GetTargets() {
    var validTarget = Smurf.Objects.Players.Where(p => p.IsAlive && !p.IsDormant && p.Id != Smurf.LocalPlayer.Id);
    //Only gets the targets that is seen by me the localplayer.
    if (_aimSpotted)
        validTarget = validTarget.Where(p => p.SeenBy(Smurf.LocalPlayer));
    if (_aimEnemies)
        validTarget = validTarget.Where(p => !p.IsFriendly);
    if (_aimAllies)
        validTarget = validTarget.Where(p => p.IsFriendly);

    return validTarget;
}

这就是我使用该方法的方法:

                IEnumerable<Player> validTarget = GetTargets();

但问题是validTarget仍会包含ID与我的LocalPlayer相同的目标。

enter image description here

2 个答案:

答案 0 :(得分:4)

您正在查看validTarget.source,这是您最初传递给Where()的集合。

如果您查看结果(展开对象中的最后一项),您将会看到已过滤的项目。

答案 1 :(得分:0)

您可能遇到与延期执行相关的问题。当你返回LINQ语句时,它还没有实际执行;它实际枚举可枚举时执行。 Smurf.LocalPlayer.Id实际上并没有解决,直到发生这种情况。您可以通过将Smurf.LocalPlayer.Id设置为局部变量来强制它使用显式值,然后在方法返回之前包含在where子句中 - 或 - 强制执行(例如,使用ToArray())。 选项#1通常更可取。 例:     var localPlayerId = Smurf.LocalPlayer.Id     var validTarget = Smurf.Objects.Players.Where(p =&gt; p.IsAlive&amp;&amp;!p.IsDormant&amp;&amp; p.Id!= localPlayerId);