5

在列表上运行 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() 行。原因是什么?

4

3 回答 3

15

someEnumerable.Single(...)如果someEnumerable. 鉴于您刚刚声明tempList为空列表,它总是会抛出异常。

如果要null在没有元素的情况下检索,请使用SingleOrDefault. (如果 enumerable 包含多个元素,这仍然会引发异常。)如果您想要第一个元素,以便允许您的 enumerable 包含任意数量的元素,请使用First(如果 enumerable 不包含任何元素,则引发异常)或FirstOrDefault(返回null的情况下)。

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

于 2010-10-13T05:45:47.573 回答
0

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

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

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

于 2012-10-29T07:30:01.107 回答
0

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

于 2012-10-28T06:43:23.767 回答