Цепочка конструктора должна быть определена наверняка во время компиляции - компилятор должен выбрать перегрузку, чтобы он мог создать действительный IL.В то время как обычно разрешение перегрузки (например, для вызовов методов) может быть отложено до времени выполнения, это не работает для связанных вызовов конструктора.
РЕДАКТИРОВАТЬ: В "нормальном" коде C # (в основном, до C # 4), все разрешение перегрузки выполняется во время компиляции.Однако, когда вызов члена включает динамическое значение, которое разрешается во время выполнения.Например, рассмотрим следующее:
using System;
class Program
{
static void Foo(int x)
{
Console.WriteLine("int!");
}
static void Foo(string x)
{
Console.WriteLine("string!");
}
static void Main(string[] args)
{
dynamic d = 10;
Foo(d);
}
}
Компилятор здесь не отправляет прямой вызов Foo
- не может, потому что при вызове Foo(d)
он не знает, какая перегрузка будетразрешитьВместо этого он генерирует код, который выполняет своего рода мини-компиляцию «точно в срок», чтобы разрешить перегрузку с типом фактическим значения d
во время выполнения.
Теперь, когдане работает для цепочки конструктора, так как действительный IL должен содержать вызов определенного конструктора базового класса.(Я не знаю, может ли динамическая версия даже быть выраженной в IL, или может ли она быть, но результат будет непроверенным.)
Можно утверждать, что C #компилятор должен быть в состоянии сказать, что на самом деле есть только один видимый конструктор, который может быть вызван, и этот конструктор будет всегда доступным ... но как только вы начнете идти по этому пути, вы закончитес языком, который очень сложно определить.Разработчики C # обычно занимают более простые правила, которые иногда бывают не такими мощными, как хотелось бы.