Reputation: 3860
This error is being thrown when running a Linq query over a List.
I am using Unity3D 3.0 with C# (Unity3D uses Mono 2.6). Unity3D, as far as I know, is single-threaded. It works by attaching "scripts" (c# .cs files) that inherit a baseclass, to a "GameObject". Also, Unity controls instantiation and serialization of scripts so you can't use constructors.
I have a RoadNetwork script that holds a reference to RoadNodes and RoadCurves, both of which locate RoadNetwork via a singleton and register/deregister themselves. I've put "mini-factories" in RoadNode and RoadCurve that do the hard work of hooking themselves up to a gameobject.
RoadNode first checks with RoadNetwork to make sure there isnt already a node at that same position, by doing this:
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;
}
Where the appropriate method in RoadNetwork is:
public RoadNode2 GetNodeAtPosition(Vector3 position)
{
var tempList = new List<RoadNode2>();
return tempList.Single(x => x.Position == position);
}
tempList was an attempt at narrowing down the problem but I get precisely the same error. It should be "Nodes.Single(...", but I doubt it matters. I get the same error if I call the Linq query directly in the New() method.
So yes, this Exception throws and points me to that tempList.Single() line. What would the reason be?
Upvotes: 5
Views: 33182
Reputation: 4195
It sounds like there's a problem with the way you're implementing the singleton pattern in Unity. If you're getting a null reference exception when checking a list that mean the list hasn't been initialized, so you're probably either not instantiating the singleton or your not accessing the singleton you instantiated.
I usually use a singleton MonoBehaviour attached to a GameObject that instantiates and initializes on first access like this:
http://answers.unity3d.com/questions/156746/singleton-and-monobehaviour-in-editor.html
Upvotes: 0
Reputation: 2011
I think what Domenic meant to say was that .Single() throws an error whenever more than one element matches your predicate. Your collection someEnumerable must contain duplicate copies of whatever singleton (not the programming pattern) you're trying to retrieve.
Upvotes: 0
Reputation: 112837
someEnumerable.Single(...)
throws an exception if there is not exactly one element in someEnumerable
. Given that you just declared tempList
to be an empty list, it will always throw an exception.
If you want to retrieve null
if there are no elements, use SingleOrDefault
. (This will still throw an exception if the enumerable contains more than one element.) If you want the first element, so that your enumerable is allowed to contain any number of elements, use First
(throws an exception if the enumerable contains no elements) or FirstOrDefault
(returns null
in the case).
Finally, if you want to simply check if there are any elements of a list matching a given predicate, use Any
.
Upvotes: 15