Почему 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
ссылка.