Почему структура в массиве не требуется инициализировать? - программирование
Подтвердить что ты не робот

Почему структура в массиве не требуется инициализировать?

Я исследовал эту тему, но я не мог найти ни одного дубликата. Мне интересно, почему вы можете использовать struct в массиве без создания экземпляра.

Например, у меня есть class и struct:

public class ClassAPI
{
    public Mesh mesh { get; set; }
}

public struct StructAPI
{
    public Mesh mesh { get; set; }
}

Когда ClassAPI используется в массиве, он должен быть инициализирован new ключевым словом, прежде чем использовать его свойства и методы:

ClassAPI[] cAPI = new ClassAPI[1];
cAPI[0] = new ClassAPI(); //MUST DO THIS!
cAPI[0].mesh = new Mesh();

Но это не относится к StructAPI. Похоже, что StructAPI не нужно инициализировать в массиве:

StructAPI[] sAPI = new StructAPI[1];
sAPI[0].mesh = new Mesh();

Если вы попробуете то же самое с ClassAPI, вы получите NullReferenceException.

Почему это отличается от структуры при использовании их в массиве?

Я понимаю разницу между class и struct когда struct является типом значений, но это все еще не имеет смысла. Для меня, без участия массива в этом, было бы похоже, что я это делаю:

StructAPI sp;
sp.mesh = new Mesh();

Обратите внимание, что переменная sp не инициализирована и должна приводить к ошибке времени компиляции:

Ошибка CS0165 Использование неназначенной локальной переменной sp

но это другая история, когда struct помещается в массив.

Является ли массив инициализацией struct в нем? Я хотел бы знать, что происходит.

4b9b3361

Ответ 1

В соответствии со спецификацией, указанной PetSerAl в комментариях:

Элементы массива
Элементы массива возникают при создании экземпляра массива и перестают существовать, когда нет ссылок на этот массив.

Начальным значением каждого из элементов массива является значение по умолчанию (значения по умолчанию) типа элементов массива.

Для определенной проверки назначения элемент массива считается первоначально назначенным.

(акцент мой).

Это означает, что когда вы объявляете массив из T, каждая "ячейка" в массиве инициализируется с использованием default(T) по default(T). Для ссылочных типов default(T) возвращает значение null, но для типов значений по default(T) возвращает значение по умолчанию типа - 0 для чисел, false для bool и т.д.

В соответствии с руководством по использованию Structs (С# Programming Guide):

Если вы создаете экземпляр объекта struct с использованием конструктора без параметров без параметров, все члены назначаются в соответствии со своими значениями по умолчанию.

Поскольку структуры являются типами значений, default(T) где T является структурой, инициализирует структуру значением по умолчанию, то есть все ее члены будут инициализированы значениями по умолчанию - null для ссылочных типов и любым значением по умолчанию для типов значений.

Итак, эта строка кода StructAPI[] sAPI = new StructAPI[1]; в основном создает новый массив StructAPI содержащий один экземпляр StructAPI, где его свойство mesh по default(Mesh).

Ответ 2

Вероятно, это связано с тем, что у классов, когда у них есть конструктор по умолчанию, у структур на самом деле их нет.

Почему классные массивы должны быть проиндексированы

Классы создают объект, а затем возвращают ссылку. Фактическая переменная является ссылкой на это значение. Значения по умолчанию всегда равны null, поэтому значение по умолчанию для ссылки равно null, поскольку null представлен адресом всех нулей, что означает, что он не указывает ни на что.

Из-за этого значением по умолчанию для массива класса являются все нулевые ссылки.

Почему массивы структур не обязательно должны быть

Структуры, с другой стороны, все по стоимости. У них также нет конструктора без параметров, и С# не позволяет вам создать его (хотя CLR делает). Из-за того, что конструктор не существует, CLR может очень эффективно создавать структуру, обнуляя все значения без вызова конструктора.

Вы можете узнать больше о том, почему это из этого вопроса StackOverflow.

Ответ 3

Когда вы инициализируете массив, значения по умолчанию присваиваются его элементам:

  • null для ссылочных типов,
  • для типов значений значение по умолчанию меняется: ноль для типов, представляющих числа, для struct он немного отличается, его значение по умолчанию - это struct со всеми полями, установленными в их значения по умолчанию. Опять же, для ссылочных типов это значение null и для типов значений зависит (как упоминалось выше).

Итак, в основном, когда вы инициализируете массив, у вас есть инициализированная struct (значение по умолчанию), поэтому вы можете получить доступ к их свойствам.