2012-07-31 2 views
5

Рассмотрим класс вроде этого:Строка литой не работает

public class MyString 
{ 
private string _string; 

public string String 
{ 
    get { return _string; } 
    set { _string = value; } 
} 

public MyString(string s) 
{ 
    _string = s; 
} 

public static implicit operator string(MyString str) 
{ 
    return str.String; 
} 

public static implicit operator MyString(string str) 
{ 
    return new MyString(str); 
} 
} 

Как сделать следующий код работать?

MyString a = "test"; 
object b = a; 
var c = (string)b; 

Теперь я получаю это исключение:

InvalidCastException: Не удается привести объект типа 'MyString' для типа 'System.String'.

+0

насчет вар с = b.ToString()? –

ответ

2

настраиваемой литой является функцией в маскировке. Выполняется ли фактический отбор или вызывается пользовательский оператор преобразования, зависит от типа времени компиляции выражаемого выражения.

В вашем примере тип времени компиляции выражаемого слова 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, который не является результатом строки (и не может, поскольку строка запечатана).

Дело в том, что в то время как пользовательские преобразования (определенные с использованием неявного или явного) имеют тот же синтаксис, что и приведения, они совершенно отличны от приведения. Литая никогда не оставит цепочку наследования (в том числе наследуемых интерфейсов) вы можете идти вверх или вниз по цепочке с броском, но никогда не оставить

4

Пользовательские неявные/явные операторы работают только между напечатал значения - не object. Такой листинг всегда является либо базовой проверкой типа, либо распаковкой. Неявное приведение:

string s = a; 
-1

Вы должны попробовать:

public MyString:String 
{ 
//code 
} 
+1

строка запечатана. – Jamiec

+0

oops :) да, ты прав – asd007

2

Вы можете попытаться изменить последнюю строку:

string c = (string)((MyString)b); 
Смежные вопросы