2010-10-13 9 views
5

Ten błąd jest zgłaszany podczas uruchamiania zapytania Linq nad listą.Operacja jest nieprawidłowa z powodu aktualnego stanu obiektu - Linq na liście

Używam Unity3D 3.0 z C# (Unity3D używa Mono 2.6). Unity3D, o ile mi wiadomo, jest jednowątkowe. Działa poprzez dołączenie "skryptów" (pliki C# .cs), które dziedziczą klasę bazową, do "GameObject". Ponadto, Unity kontroluje tworzenie instancji i serializację skryptów, więc nie można używać konstruktorów.

Mam skrypt RoadNetwork, który zawiera odniesienie do RoadNodes i RoadCurves, które lokalizują RoadNetwork przez singleton i rejestrują się/wyrejestrowują się. Umieściłem "mini-fabryki" w RoadNode i RoadCurve, które wykonują ciężką pracę polegającą na podłączeniu się do obiektu gry.

RoadNode sprawdza najpierw z RoadNetwork, aby upewnić się nie ma zbyt już węzeł w tym samym miejscu, w ten sposób:

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; 
} 

Gdzie odpowiednia metoda w RoadNetwork jest:

public RoadNode2 GetNodeAtPosition(Vector3 position) 
{ 
    var tempList = new List<RoadNode2>(); 

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

tempList było próba zawężenia problemu, ale dostaję dokładnie ten sam błąd. Powinno być „Nodes.Single (...”, ale wątpię, że się liczy. I uzyskać ten sam błąd, jeśli zadzwonię kwerendy Linq bezpośrednio w metodzie new().

Więc tak, ten wyjątek rzuty i punkty mnie do tego tempList.Single() online. Co by być powodem?

Odpowiedz

13

someEnumerable.Single(...) zgłasza wyjątek, jeśli nie ma dokładnie jeden element someEnumerable. Biorąc pod uwagę, że po prostu oświadczył tempList być pustą listę, to zawsze rzucać wyjątek:

Jeśli chcesz odzyskać null, jeśli nie ma elementów, użyj SingleOrDefault. (To będzie nadal powodować wyjątek, jeśli przeliczalne Zawiera więcej niż jeden element.) Jeśli chcesz pierwszy elementu, tak że przeliczalna może zawierać dowolną liczbę elementów, użyj First (zgłasza wyjątek, jeśli przeliczalny nie zawiera żadnych elementów) lub FirstOrDefault (zwraca null w walizka).

Na koniec, jeśli chcesz po prostu sprawdzić, czy są jakieś elementy listy pasujące do danego predykatu, użyj Any.

+0

Dzięki, nie wiedziałem, że niektóre, ale nie jest to błąd (otrzymam null ref).To, że kolekcja z jakiegokolwiek powodu nie jest ważna ze względu na jej stan. –

+3

Ciężko Ci pomóc, jeśli nie napiszesz dokładnego błędu. Ponadto, zgodnie z http://msdn.microsoft.com/en-us/library/bb155325.aspx, wynikiem użycia 'Single' na przeliczalnym, niezupełnie jednym elemencie jest' InvalidOperationException', nie jest to rodzaj referencji zerowej wyjątek. – Domenic

+0

Po prostu chcę powiedzieć, że wersje "OrDefault" działały w mojej konkretnej sytuacji. Używam również Unity i otrzymuję ten sam wyjątek InvalidOperation. W moim przypadku użyłem 'collection.First()' w LINQ. Zmiana tego na '.FirstOrDefault' naprawiła to. Wersje metody LINQ "OrDefault" są zawsze bezpieczne, jak się wydaje. – Aaron

0

Myślę, że Domenic chciał powiedzieć, że .Single() zgłasza błąd, gdy więcej niż jeden element pasuje do twojego predykatu. Twoja kolekcja someEnumerable musi zawierać duplikaty tego, co singleton (nie wzorzec programowania), który próbujesz odzyskać.

0

Wygląda na to, że jest problem ze sposobem, w jaki implementujesz wzór singletonowy w Unity. Jeśli podczas sprawdzania listy, która oznacza, że ​​lista nie została zainicjalizowana, otrzymujesz wyjątek o wartości zerowej, więc prawdopodobnie nie tworzysz pojedynczej instancji ani nie uzyskujesz dostępu do singletonu, który stworzyłeś.

Zwykle używam singleton MonoBehaviour dołączony do GameObject'u że instancję i inicjuje przy pierwszym dostępie jak ten:

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

Powiązane problemy