Я получаю сообщение об ошибке при компиляции этого кода:
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'
}
}
Привет!
Компилятор говорит: «Использование неназначенной локальной переменной 'vector'» и указывает на возвращаемое значение. Мне кажется, что Vector2 стал ссылочным типом (без члена события он действует нормально). Что происходит?





В C# вам все равно нужно «создать» структуру для вызова конструктора, если только вы не инициализируете поля все. Вы оставили элемент EventHandler «триггер» неназначенным.
Попробуйте назначить «триггер» или использовать:
Vector2 vector = new Vector2()
Новый объект нет размещен в куче, он по-прежнему размещен в стеке функций.
Процитируем MSDN:
When you create a struct object using the new operator, it gets created and the appropriate constructor is called. Unlike classes, structs can be instantiated without using the new operator. If you do not use new, the fields will remain unassigned and theobject cannot be used until all of the fields are initialized.
Вы должны иметь возможность инициализировать его значением null
Мне нравится инициализировать свои события как '= delegate {};', поэтому мне не нужно проверять значение null при запуске события.
У Роба Уокера ответ лучше, поскольку он начал с документации, а затем обосновал код (тогда как я пошел другим путем).
Если вы скомпилируете пример кода с закомментированным полем триггера, а затем запустите IlAsm, чтобы получить результирующий MSIL, вы увидите, что для вектора локальной переменной нет кода операции initobj.
Отсутствие initobj нормально, когда структура Vector2 содержит только типы значений. В конце концов, это всего лишь сырые воспоминания. Однако, если структура Vector2 также содержит ссылку, она должна быть инициализирована, чтобы предотвратить наличие неинициализированной ссылки на объект.
Чтобы избежать возврата частично унифицированного объекта, вам необходимо явно записать в обработчик событий trigger или инициализировать весь объект с помощью новой операции. Однако ни в коем случае конструкция не превращается в эталонный тип.
Другие объяснили способы решения этой проблемы, но я думаю, что стоит упомянуть еще одну большую проблему с вашим кодом: у вас есть изменяемая структура. Это в значительной степени всегда плохая идея. Это обязательно будет лишь первой из многих проблем, с которыми вы столкнетесь, если так и останетесь.
Я сильно рекомендую вам либо сделать его неизменяемым, либо сделать его классом.
Я решительно поддержу это - изменяемые структуры всегда причиняют больше боли, чем люди ожидают.
Создание структур с изменяемыми членами рискованно. Либо используйте класс, либо отметьте поля как «только для чтения».