Почему `this` недоступен в инициализации Auto-Property С# 6.0?
У меня есть следующий класс кода:
public class Foo
{
public Nested Bar { get; } = new Nested(this);
public class Nested
{
public Nested(Foo foo)
{
foo.DoSomething();
}
}
private void DoSomething()
{
}
}
Однако я получаю эту ошибку компиляции:
Ключевое слово 'this' недоступно в текущем контексте
Я могу исправить это, просто не используя Auto-Property Initializer и явно переместив его в конструктор:
public Nested Bar { get; }
public Foo()
{
this.Bar = new Nested(this);
}
Почему так? Не инициализатор автоисторического значения фактически переведен в код конструктора в IL?
Ответы
Ответ 1
Просто: вы не можете использовать this
в инициализаторах. Идея состоит в том, чтобы предотвратить утечку незавершенного объекта - Nested(this)
может что-то сделать для вашего объекта, что приводит к очень запутывающим и трудным для понимания ошибкам. Имейте в виду, что инициализаторы выполняются перед любым добавленным конструктором. То же самое происходит и для инициализаторов полей точно так же:
private Nested _field = new Nested(this);
По сути, инициализаторы предназначены для выполнения простых инициализаций - исправления 98% -ной проблемы. Все, что связано с this
, является более сложным, и вам нужно будет написать свой собственный конструктор - и взять на себя ответственность за любые проблемы времени:)
Ответ 2
Почему так? Не инициализатор автоисторического значения фактически переведен в код конструктора в IL?
Правила для автоматически реализованных инициализаторов свойств такие же, как и для инициализаторов полей по той же причине. Обратите внимание, что инициализаторы свойств выполняются перед телами базового класса, как и инициализаторы полей, поэтому вы все еще находитесь в контексте "несколько неинициализированного" объекта; больше, чем во время тела конструктора.
Итак, вы должны представить, что свойство преобразуется в это:
private readonly Nested bar = new Nested(this); // Invalid
public Nested Bar
{
get { return bar; }
}
Короче говоря, это ограничение должно помешать вам попасть в неприятности. Если вам нужно ссылаться на this
при инициализации свойства, просто сделайте это вручную в конструкторе согласно вашему второму примеру. (Это относительно редко по моему опыту.)