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

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

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 внутри структуры, но не поле non-static?
  • Почему мы должны инициализировать non-static в телах методов?

person Asad    schedule 21.02.2010    source источник
comment
Будет ли каждый экземпляр Animal весить 20 единиц и не иметь имени? Может быть, вы ищете конструктор. (Простите мою терминологию, если она неверна.)   -  person GManNickG    schedule 21.02.2010


Ответы (4)


Взгляните на Почему типы значений не могут иметь Конструкторы по умолчанию?

person Adriaan Stander    schedule 21.02.2010
comment
Хотя на уровне IL они могут: msmvps.com/blogs/jon_skeet/archive/2008/12/10/ - person Jon Skeet; 21.02.2010
comment
Ссылка сейчас не работает - person Dominic; 13.09.2013

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

person supercat    schedule 23.11.2011

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

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

person mmx    schedule 21.02.2010

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

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

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

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

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

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

person Daniel Earwicker    schedule 21.02.2010
comment
Эта структура не будет компилироваться, в структурах не должно быть инициализаторов полей экземпляров. - person K Scandrett; 12.07.2017