Почему я получаю эту ошибку при создании и возврате новой структуры? - PullRequest
3 голосов
/ 18 ноября 2008

Я получаю сообщение об ошибке при компиляции этого кода:

using System;

public struct Vector2
{
    public event EventHandler trigger;

    public float X;
    public float Y;

    public Vector2 func()
    {
        Vector2 vector;
        vector.X = 1;
        vector.Y = 2;
        return vector;  // error CS0165: Use of unassigned local variable 'vector'
    }
}

привет! * * 1004

Компилятор говорит: «Использование неназначенной локальной переменной vector» и указывает на возвращаемое значение. Мне кажется, что Vector2 стал ссылочным типом (без элемента события он работает нормально). Что происходит?

Ответы [ 3 ]

14 голосов
/ 18 ноября 2008

В C # вам все еще нужно «создать» новую структуру для вызова конструктора, если только вы не инициализируете все поля. Вы оставили элемент триггера EventHandler неназначенным.

Попробуйте назначить 'триггер' или использовать:

Vector2 vector = new Vector2()

Новый объект не размещен в куче, он все еще расположен в стеке функций.

Цитировать MSDN :

Когда вы создаете объект структуры с помощью новый оператор, он создается и соответствующий конструктор называется. В отличие от классов, структуры могут быть создан без использования нового оператор. Если вы не используете новый, поля останутся неназначенными и the объект не может быть использован , пока все поля инициализируются.

2 голосов
/ 18 ноября 2008

Другие объяснили, как это обойти, но я думаю, что стоит упомянуть еще одну большую, большую проблему с вашим кодом: у вас есть изменяемая структура. Это в значительной степени всегда плохая идея. Это неизбежно будет лишь первой из многих проблем, с которыми вы столкнетесь, если будете продолжать в том же духе.

Я настоятельно рекомендую либо сделать его неизменным, либо сделать его классом.

1 голос
/ 18 ноября 2008

У Роба Уолкера лучший отклик, поскольку он начал с документов, а затем обосновал код (тогда как я пошел другим путем).

Если вы скомпилируете пример кода с закомментированным полем триггера, а затем запустите IlAsm для получения результирующего MSIL, вы увидите, что для локальной переменной vector нет кода операции initobj.

Отсутствие initobj хорошо, когда структура Vector2 содержит только типы значений. В конце концов, они просто сырая память. Однако, если структура Vector2 также содержит ссылку, она должна быть инициализирована, чтобы не иметь ссылки на неинициализированный объект.

Чтобы избежать возврата частично унитализированного объекта, вам необходимо явно записать в обработчик события trigger или инициализировать весь объект с помощью новой операции. Однако ни в коем случае структура не превращается в ссылочный тип.

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