настраиваемой литой является функцией в маскировке. Выполняется ли фактический отбор или вызывается пользовательский оператор преобразования, зависит от типа времени компиляции выражаемого выражения.
В вашем примере тип времени компиляции выражаемого слова Ie. тип выражения b
равен object
, тип object
не имеет специального преобразования в строку. Однако листинг может быть действителен и поэтому допускается компилятором.
MyString a = "test";
object b = a;
var c = (string)b;
string d = a;
var e = (string)a;
Четвертая строка будет рассматриваться как // называет Funciton определяется как пользовательские преобразования строки д = MyString.op_implicit (а);
То же самое верно для пятой линии. Пятая строка, хотя она использует синтаксис для литья не отличное преобразование.
Однако третья строка выглядит как литой и литой. Приведение заключается в том, что вы сообщаете компилятору, что у вас есть дополнительная информация относительно типа объекта , чем у компилятора. (string)a
сообщает компилятору, что он может быть уверен, что объект, представленный a, будет иметь тип строки выполнения. В вашем случае это неверно, он имеет тип MyString
, который не является результатом строки (и не может, поскольку строка запечатана).
Дело в том, что в то время как пользовательские преобразования (определенные с использованием неявного или явного) имеют тот же синтаксис, что и приведения, они совершенно отличны от приведения. Литая никогда не оставит цепочку наследования (в том числе наследуемых интерфейсов) вы можете идти вверх или вниз по цепочке с броском, но никогда не оставить
насчет вар с = b.ToString()? –