Почему нестатические поля не могут быть инициализированы внутри структур? - PullRequest
20 голосов
/ 21 февраля 2010

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

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

Ответы [ 4 ]

7 голосов
/ 21 февраля 2010
1 голос
/ 23 ноября 2011

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

0 голосов
/ 21 февраля 2010

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

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

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

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

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

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

0 голосов
/ 21 февраля 2010

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

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

...