Почему C# не разрешает инициализатор полей с нестатическими полями?

Почему C# позволит этого :

public class MyClass
{
  static int A=1;
  static int B=A+1;
}

но не позволит ("инициализатор поля не может ссылаться на нестатические поля, метод или свойство") это

public class MyClass
{
   int A=1;
   int B=A+1;
}

Я думал, что это ордер это гарантировано (со статическими полями) для последовательной инициализации , как кажется, но он также применяется здесь как видите:

public class MyClass
{
   int A=((Func<int>)(delegate(){ Console.WriteLine ("A"); return 1;}))();
   int B=((Func<int>)(delegate(){ Console.WriteLine ("B"); return 2;}))();
   int C=((Func<int>)(delegate(){ Console.WriteLine ("C"); return 3;}))();
}

void Main()
{
 var a = new MyClass();
}

результат :

A
B
C

вопрос

меня больше интересует разум/логика почему он был ограничен. просто из любопытства.

NB не нашел дубликата.

2 ответов


меня больше интересует причина / логика, почему она была ограничена. просто из любопытства.

если Вы читаете спецификацию языка C#, 10.11.3, это намекает на обоснование здесь. При обсуждении инициализаторы переменной:

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

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

обратите внимание, что это согласуется с how static поля также работают. В обоих случаях вы are разрешен доступ к статическим данным, но не к данным экземпляра. Сообщение об ошибке ("инициализатор поля не может ссылаться на нестатическое поле, метод или свойство" ) непосредственно отмечает этот.


" используйте статический модификатор для объявления статического элемента, который принадлежит самому типу, а не конкретному объекту."-статический MSDN

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

С другой стороны, когда A и B не являются статическими, они принадлежат только экземпляру MyClass. При компиляции, поле B попытается инициализироваться на основе значения из A который еще не был инициализирован. Нет никакого экземпляра MyClass во время работы компилятора и, следовательно, нет значения A ссылка.