Ответ 1
Посмотрите Почему типы значений не имеют конструкторы по умолчанию?
Рассмотрим этот блок кода:
struct Animal
{
public string name = ""; // Error
public static int weight = 20; // OK
// initialize the non-static field here
public void FuncToInitializeName()
{
name = ""; // Now correct
}
}
static
внутри поля struct, но не non-static
?non-static
в телах методов?Посмотрите Почему типы значений не имеют конструкторы по умолчанию?
CLI ожидает, что сможет выделять и создавать новые экземпляры любого типа значений, которые потребуют "n" байт памяти, просто выделяя "n" байты и заполняя их нулем. Там нет причин, по которым CLI "не может" предоставить средство указания либо того, что до того, как какой-либо объект, содержащий структуры, станет доступным для внешнего кода, конструктор должен быть запущен на каждой структуре в нем или что всякий раз, когда экземпляр конкретного n- byte struct создается, компилятор должен скопировать "экземпляр шаблона". Однако, как это, CLI не допускает такой вещи. Следовательно, нет никаких причин для компилятора притворяться, что у него есть средство гарантировать, что структуры будут инициализированы ничем, кроме значения по умолчанию, заполненного памятью с нулями.
Вы не можете написать собственный конструктор по умолчанию в структуре. Инициализаторы полей экземпляра в конечном итоге должны быть перемещены в конструктор, который вы не можете определить.
Инициализаторы статического поля перемещаются в статический конструктор. Вы можете написать собственный статический конструктор в структуре.
Вы можете делать именно то, что вы пытаетесь сделать. Все, что вам не хватает, это настраиваемый конструктор, который вызывает конструктор по умолчанию:
struct Animal
{
public string name = "";
public static int weight = 20;
public Animal(bool someArg) : this() { }
}
Конструктор должен взять хотя бы один параметр, а затем он должен перейти к this()
, чтобы инициализировать элементы.
Причина этого заключается в том, что теперь у компилятора есть способ узнать, когда код должен запускаться для инициализации поля name
: всякий раз, когда вы пишете new Animal(someBool)
.
С любой структурой вы можете сказать new Animal()
, но "пустые" животные могут быть созданы неявно во многих случаях в работе CLR, и нет способа гарантировать, что пользовательский код запускается каждый раз, когда это происходит.