Это не приведет к ошибке во время компиляции, потому что является допустимым закрытием.
Проблема в том, что this
еще не инициализирован во время создания закрытия. Ваш конструктор еще не запущен, когда этот аргумент указан. Таким образом, результирующее NullReferenceException
на самом деле вполне логично. Это this
это null
!
Я докажу это тебе. Давайте перепишем код следующим образом:
class Program
{
static void Main(string[] args)
{
var test = new DerivedTest();
object o = test.Func();
Console.WriteLine(o == null);
Console.ReadLine();
}
}
class BaseTest
{
public BaseTest(Func<object> func)
{
this.Func = func;
}
public Func<object> Func { get; private set; }
}
class DerivedTest : BaseTest
{
public DerivedTest() : base(() => this)
{
}
}
Угадайте, что это печатает? Да, это true
, замыкание возвращает null
, потому что this
не инициализируется при выполнении.
Редактировать
Мне было любопытно высказывание Томаса о том, что, возможно, они изменили поведение в следующем выпуске VS. На самом деле я обнаружил проблему Microsoft Connect об этой самой вещи. Он был закрыт как "не починить". Одд.
Как Microsoft говорит в своем ответе, обычно недопустимо использовать ссылку this
из списка аргументов вызова базового конструктора; ссылка просто не существует в этот момент времени, и вы получите ошибку во время компиляции, если попытаетесь использовать ее «голым». Таким образом, возможно, что должен вызвать ошибку компиляции для случая закрытия, но ссылка this
скрыта от компилятора, который (по крайней мере в VS 2008) должен был бы знать look за это внутри затвора, чтобы люди этого не делали. Это не так, вот почему вы в конечном итоге с таким поведением.