Почему вы не можете использовать 'this' в инициализаторах членов?

Возможный дубликат:
Нельзя использовать это в инициализаторе члена?

Любые идеи, почему я получаю сообщение об ошибке, если я попытаюсь сделать что-то вроде этого:

public class Bar
{
    public Bar(Foo foo)
    {
    }
}

public class Foo
{
    private Bar _bar = new Bar(this);
}

Я получаю сообщение об ошибке:

"Невозможно использовать 'this' в инициализаторе элемента"

но следующие работы:

public class Foo
{
    private Bar _bar;

    public Foo()
    {
        _bar = new Bar(this);
    }
}

Кто-нибудь знает причину этого? Мое понимание заключалось в том, что они скомпилировались бы с тем же ИЛ, поэтому любопытно, почему один разрешен, а другой нет.

Спасибо, Alex

Ответ 1

Я подозреваю, что это мешает вам использовать объект до запуска конструктора базового класса, гарантируя, что все члены базового класса будут правильно инициализированы. (Переменные инициализаторы выполняются перед конструктором базового класса, тогда как тело конструктора выполняется после этого.)

Будет проверять, есть ли в аннотированной спецификации что-нибудь об этом, когда я буду рядом с ней...

EDIT: спецификация С# 4 для аннотирования не содержит никаких объяснений. Просто (в 10.5.5.2):

Инициализатор переменных для поля экземпляра не может ссылаться на создаваемый экземпляр.

Ответ 2

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

17.10.2 Инициализаторы переменных экземпляра:

Если конструктор экземпляра не имеет инициализатор конструктора, или он имеет инициализатор конструктора формы base (...), что конструктор неявно выполняет указанные инициализации переменными-инициализаторами поля экземпляра, объявленные в его классе. Это соответствует последовательности выполняемые задания сразу после входа в конструктор и перед неявным вызов прямого базового класса конструктор. Переменная инициализаторы выполняются в текстовый порядок, в котором они появляются объявление класса.

Ответ 3

Я считаю, что это потому, что поля инициализируются перед инициализацией класса, поэтому, когда выполняется следующий код:

private Bar _bar = new Bar(this);

"this" не имеет фактического значения для ссылки.

При помещении его в конструктор означает, что есть экземпляр "Foo", реферируемый "this"

Ответ 4

В С# никакая логика не предназначена для внешних методов и свойств.

Инициализаторы полей являются исключением, но с некоторыми ограничениями.

Неправильно получить ссылку на текущий объект с ключевым словом this, потому что объявление поля класса не является логическим, а классным, а этот является частью run- временная семантика.

Кстати, это, по-видимому, решение для дизайна С#, , потому что на самом деле инициализатор поля запускается во время построения класса, поэтому "текущий экземпляр класса объявления" должен быть доступен через this. Но опять же, что было бы this вне области действия метода или свойства?

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

Ответ 5

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

Если вы используете 'this' в конструкторе → , все члены с инициализаторами были инициализированы. Так что все в порядке.

Если вы используете 'this' в инициализаторе элемента: другие члены (с прикрепленными инициализаторами) еще не могут быть инициализированы → 'this' еще не готовы. Вот почему использование 'this' запрещено здесь не допускается.