Вы не должны удивляться - пользовательские операторы не переопределяют что-либо, они перегружают - поэтому они выбираются во время компиляции , а не время исполнения .
Когда мы удаляем неявную типизацию из кода, она становится немного понятнее:
object bInstanceReflection = Activator.CreateInstance(typeof (B));
Console.WriteLine(bInstanceReflection.GetType()); // <assemblyname>.B
A aInstanceReflection = (A) bInstanceReflection;
Теперь достаточно ясно, что в последней строке (A)
- это просто приведение от object
, которое выполняет обычное преобразование ссылок. Пользовательские преобразования не будут применяться вообще.
Если вы используете .NET 4, вы можете использовать динамическую типизацию, чтобы заставить его работать:
// Note the change of type
dynamic bInstanceReflection = Activator.CreateInstance(typeof (B));
Console.WriteLine(bInstanceReflection.GetType()); // <assemblyname>.B
A aInstanceReflection = (A) bInstanceReflection;
Теперь преобразование применяется к динамическому значению, что означает, что выбор используемого преобразования откладывается до времени выполнения - в этот момент он будет использовать ваш пользовательский оператор.