由于对象的当前状态,操作无效 - Linq on List

Posted

技术标签:

【中文标题】由于对象的当前状态,操作无效 - Linq on List【英文标题】:Operation is not valid due to the current state of the object - Linq on List 【发布时间】:2011-04-24 16:16:44 【问题描述】:

在 List 上运行 Linq 查询时会引发此错误。

我在 C# 中使用 Unity3D 3.0(Unity3D 使用 Mono 2.6)。据我所知,Unity3D 是单线程的。它通过将继承基类的“脚本”(c# .cs 文件)附加到“游戏对象”来工作。此外,Unity 控制脚本的实例化和序列化,因此您不能使用构造函数。

我有一个 RoadNetwork 脚本,其中包含对 RoadNodes 和 RoadCurves 的引用,它们都通过单例定位 RoadNetwork 并自行注册/注销。我在 RoadNode 和 RoadCurve 中放置了“迷你工厂”,它们负责将自己连接到游戏对象。

RoadNode 首先检查 RoadNetwork 以确保在同一位置没有节点,这样做:

public static RoadNode2 New(float x, float y, float z)

    //First try to find an existing one
    var rn = RoadNetwork.Instance.GetNodeAtPosition(new Vector3(x, y, z))
             ?? UnityReferenceHelper.GetNewGameObjectFor<RoadNode2>(
                 "RoadNode_" + (RoadNetwork.Instance.Nodes.Count + 1).ToString("D3"),
                 RoadNetwork.Instance.transform.FindChild("Nodes"));

    rn.Position = new Vector3(x, y, z);

    rn.gameObject.active = true;

    return rn;

RoadNetwork 中合适的方法是:

public RoadNode2 GetNodeAtPosition(Vector3 position)

    var tempList = new List<RoadNode2>();

    return tempList.Single(x => x.Position == position);

tempList 试图缩小问题范围,但我得到了完全相同的错误。它应该是“Nodes.Single(...”,但我怀疑它是否重要。如果我直接在 New() 方法中调用 Linq 查询,我会得到同样的错误。

所以是的,这个异常抛出并指向 tempList.Single() 行。会是什么原因?

【问题讨论】:

【参考方案1】:

如果someEnumerable 中没有一个元素,someEnumerable.Single(...) 将引发异常。鉴于您刚刚将 tempList 声明为一个空列表,它总是会抛出异常。

如果您想在没有元素的情况下检索null,请使用SingleOrDefault。 (如果 enumerable 包含 more 个元素,这仍然会引发异常。)如果您想要 first 元素,那么您的 enumerable 可以包含任意数量的元素,使用First(如果枚举不包含任何元素则抛出异常)或FirstOrDefault(在这种情况下返回null)。

最后,如果您只想检查列表中是否有任何元素与给定谓词匹配,请使用Any

【讨论】:

谢谢,我不知道其中的一些,但这不是错误(我会得到一个空参考)。这就是集合由于其状态而无论出于何种原因都是无效的。 如果您不发布确切的错误,很难帮助您。此外,根据msdn.microsoft.com/en-us/library/bb155325.aspx,在不完全是一个元素的可枚举对象上使用Single 的结果是InvalidOperationException,而不是任何类型的空引用异常。 我只想说“OrDefault”版本适用于我的特定情况。我也在使用 Unity,我得到了同样的 InvalidOperation 异常。就我而言,我在 LINQ 中使用了collection.First()。将其更改为.FirstOrDefault 修复了它。 LINQ 方法的“OrDefault”版本似乎总是一个安全的选择。【参考方案2】:

我认为 Domenic 的意思是,只要有多个元素与您的谓词匹配,.Single() 就会引发错误。您的集合 someEnumerable 必须包含您尝试检索的任何单例(不是编程模式)的重复副本。

【讨论】:

【参考方案3】:

听起来您在 Unity 中实现单例模式的方式存在问题。如果您在检查列表时遇到空引用异常,这意味着该列表尚未初始化,那么您可能没有实例化单例或未访问您实例化的单例。

我通常使用附加到 GameObject 的单例 MonoBehaviour,它在第一次访问时实例化和初始化,如下所示:

http://answers.unity3d.com/questions/156746/singleton-and-monobehaviour-in-editor.html

【讨论】:

以上是关于由于对象的当前状态,操作无效 - Linq on List的主要内容,如果未能解决你的问题,请参考以下文章

由于对象的当前状态,操作无效。(SPWebApplication.Update)

条件评估失败。规则项 ID:未知,条件项 ID:未知 - 由于对象的当前状态,操作无效

在实体中查找对象和加载实体、Foreach 或在哪里使用 LinQ ON C# 的最佳性能?

TCPClient iFix 错误:当前状态下的无效操作 40020

C# LINQ to SQL 对象名称无效

ExecuteReader 需要打开连接。当前状态:破碎