Подтвердить что ты не робот

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

Рассмотрим этот блок кода:

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 в телах методов?
4b9b3361

Ответ 2

CLI ожидает, что сможет выделять и создавать новые экземпляры любого типа значений, которые потребуют "n" байт памяти, просто выделяя "n" байты и заполняя их нулем. Там нет причин, по которым CLI "не может" предоставить средство указания либо того, что до того, как какой-либо объект, содержащий структуры, станет доступным для внешнего кода, конструктор должен быть запущен на каждой структуре в нем или что всякий раз, когда экземпляр конкретного n- byte struct создается, компилятор должен скопировать "экземпляр шаблона". Однако, как это, CLI не допускает такой вещи. Следовательно, нет никаких причин для компилятора притворяться, что у него есть средство гарантировать, что структуры будут инициализированы ничем, кроме значения по умолчанию, заполненного памятью с нулями.

Ответ 3

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

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

Ответ 4

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

struct Animal
{
    public string name = ""; 
    public static int weight = 20; 

    public Animal(bool someArg) : this() { }
}

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

Причина этого заключается в том, что теперь у компилятора есть способ узнать, когда код должен запускаться для инициализации поля name: всякий раз, когда вы пишете new Animal(someBool).

С любой структурой вы можете сказать new Animal(), но "пустые" животные могут быть созданы неявно во многих случаях в работе CLR, и нет способа гарантировать, что пользовательский код запускается каждый раз, когда это происходит.