在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()行。原因是什么?
答案 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