Ответ 1
Цепочка конструктора должна быть определена для определенного во время компиляции - компилятор должен выбрать перегрузку, чтобы он мог создать действительный IL. В то время как обычно разрешение перегрузки (например, для вызовов методов) может быть отложено до времени выполнения, что не работает для вызовов цепочечных цепочек.
РЕДАКТИРОВАТЬ: В "нормальном" коде С# (до С# 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 или она может, но результат будет непроверенным.)
Вы можете утверждать, что компилятор С# должен иметь возможность сказать, что существует только один видимый конструктор, который может быть вызван, и этот конструктор будет всегда доступен... но как только вы начнете с этой дороги, вы получите язык, который очень сложно указать. Дизайнеры С# обычно занимают более простые правила, которые иногда не так сильны, как вам бы хотелось.