Концептуальная причина «Инициализатор поля не может ссылаться на нестатическое поле, метод или свойство» Ошибка CS0236

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

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

потому что "s2" ссылается на "s1".

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

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

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

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

Заранее спасибо за помощь.

ИЗМЕНИТЬ:

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

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

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

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


person Pragmateek    schedule 26.11.2010    source источник
comment
Стоит отметить, что vb.net запускает инициализаторы полей после создания базового объекта и позволяет им ссылаться на создаваемый объект. Я считаю это хорошей вещью, особенно в тех случаях, когда между полями существует инвариантная связь. Было бы еще лучше, если бы предоставление параметров конструктора инициализаторам полей было менее неуклюжим.   -  person supercat    schedule 09.05.2013


Ответы (2)


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

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)
    }
}
person Peter    schedule 26.11.2010

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

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

person Dirk Vollmar    schedule 26.11.2010
comment
Спасибо за это замечание. Вы должны быть правы, команда компилятора часто оправдывает отсутствие функций отсутствием ресурсов. Жаль, что у них не так много ресурсов, чтобы сделать C# лучше, чем он есть. - person Pragmateek; 26.11.2010