由于对象的当前状态 - 列表上的Linq,操作无效

时间:2010-10-13 05:39:56

标签: c# linq unity3d

在List上运行Linq查询时会抛出此错误。

我正在使用带有C#的Unity3D 3.0(Unity3D使用Mono 2.6)。据我所知,Unity3D是单线程的。它的工作原理是将继承基类的“脚本”(c#.cs文件)附加到“GameObject”。此外,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查询,我会得到同样的错误。

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

3 个答案:

答案 0 :(得分:15)

如果someEnumerable.Single(...)中没有一个元素,则

someEnumerable会抛出异常。鉴于您刚刚将tempList声明为空列表,它将始终抛出异常。

如果您想在没有元素的情况下检索null,请使用SingleOrDefault。 (如果可枚举包含 more 而不是一个元素,这仍会抛出异常。)如果你想要 first 元素,那么允许你的枚举包含任意数量的元素,使用First(如果可枚举不包含元素则抛出异常)或FirstOrDefault(在案例中返回null)。

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

答案 1 :(得分:0)

我认为Domenic的意思是。当单个元素与谓词匹配时,单个()会抛出错误。您的集合someEnumerable必须包含您尝试检索的任何单例(不是编程模式)的重复副本。

答案 2 :(得分:0)

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

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

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