2010-11-26 3 views
6

C# не допускает экземпляра поле инициализатора ссылаться на другое поле. Например, этот код не действует:Концептуальная причина «поле инициализатора не может ссылаться на не-статическое поле, метод или свойство» CS0236 Ошибки

class A 
{ 
string s1 = ""; 
string s2 = s1; 
} 

, потому что "s2" ссылки "s1".

Но почему это не разрешено?

Моя первая мысль была о том, что # спецификации C не гарантируют никакого порядка инициализации, но по спецификации заказа порядок декларирования:

Переменная инициализаторы выполняются в текстовом порядке которые они появляются в объявлении класса.

Таким образом, если заказ детерминирован, каковы могут быть подводные камни такого рода кода?

Заранее за вашу помощь.

EDIT:

Согласно ответам Hps, 0xA3 и Петр:

  • Порядок инициализации в сценарии наследования может быть очень запутанным,

  • , реализующий такую ​​функцию, требуют определенных ресурсов из команды разработчиков компилятора для мало пользы,

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

+0

Стоит отметить, что vb.net запускает инициализаторы полей после создания базового объекта и позволяет им ссылаться на объект, который строится. Я считаю это хорошей вещью, особенно в тех случаях, когда между полями существует инвариантная связь. Было бы даже лучше, если бы разоблачение параметров конструктора инициализаторами полей было менее неуклюжим. – supercat 2013-05-09 18:23:30

ответ

4

Эта статья может ответить на ваш вопрос.

Execution Order

+1

Итак, в основном порядок выполнения между базовыми и производными инициализаторами поля inline не определен. – Hps 2010-11-26 14:16:43

+0

Я не могу утверждать, потому что мой дневной лимит достигнут, но я обязательно сделаю следующий день. Спасибо за хорошую ссылку – TalentTuner 2010-11-26 14:22:54

+0

Спасибо за эту ссылку, это, несомненно, часть ответа. – Pragmateek 2010-11-26 14:49:36

2

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

Помимо того, что переупорядочение или реструктуризация нарушает ваш код, почему компилятор должен быть излишне сложным. Ресурсы ограничены, и команда компилятора, вероятно, предпочитает работать с функциями с более высоким приоритетом.

5

Я не уверен в поле, но кажется разумным отрицать доступ к свойствам или методам инициализатора поля. Например:

class A 
{ 
    string s1 = GetString(); 
    string s2 = this.MyString; 
    string s3 = "test"; 

    public string GetString() 
    { 
     // this method could use resources that haven't been initialized yet 
    } 

    public string MyString 
    { 
     get { return s3; } 
     // this field hasn't been initialized yet 
     // (okay, strings have a default value, but you get the picture) 
    } 
}