Операция недопустима из-за текущего состояния объекта - Linq в Списке - PullRequest
5 голосов
/ 13 октября 2010

Эта ошибка выдается при выполнении запроса Linq над списком.

Я использую Unity3D 3.0 с C # (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 (...", но я сомневаюсь, что это важно. Я получаю ту же ошибку, если вызываю запрос Linq непосредственно в методе New ().

Так что да, это исключение выдает и указывает мне на эту строку tempList.Single (). В чем причина?

Ответы [ 3 ]

15 голосов
/ 13 октября 2010

someEnumerable.Single(...) выдает исключение, если в someEnumerable нет только одного элемента. Учитывая, что вы только что объявили tempList пустым списком, он всегда выдаст исключение.

Если вы хотите получить null, если нет элементов, используйте SingleOrDefault. (Это все равно вызовет исключение, если перечислимое содержимое содержит больше , чем один элемент.) Если вы хотите, чтобы элемент first содержал так, чтобы перечисляемому элементу было разрешено содержать любое количество элементов, используйте First (выдает исключение, если перечисляемый элемент не содержит элементов) или FirstOrDefault (возвращает null в регистре).

Наконец, если вы хотите просто проверить, есть ли какие-либо элементы списка, соответствующие данному предикату, используйте Any.

0 голосов
/ 29 октября 2012

Похоже, есть проблема с тем, как вы реализуете шаблон синглтона в Unity. Если при проверке списка вы получаете исключение нулевой ссылки, это означает, что список не был инициализирован, так что вы, вероятно, либо не создаете экземпляр синглтона, либо не обращаетесь к синглтону, который вы создали.

Я обычно использую одноэлементный MonoBehaviour, присоединенный к GameObject, который создает и инициализирует при первом доступе следующим образом:

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

0 голосов
/ 28 октября 2012

Я думаю, что Доменик хотел сказать, что .Single () выдает ошибку, когда более одного элемента соответствует вашему предикату. Ваша коллекция someEnumerable должна содержать дубликаты любого синглтона (а не шаблона программирования), который вы пытаетесь получить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...