2012-07-31 11 views
5

Considérese una clase como esta:cadena no modelo de trabajo

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); 
} 
} 

¿Cómo hago el trabajo siguiente código?

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

ahora tengo esta excepción:

InvalidCastException: No se puede convertir objeto de tipo 'MiCadena' al tipo 'System.String'.

+0

¿qué pasa con var c = b.ToString()? –

Respuesta

2

un molde a medida es una función en el encubrimiento. Si se realiza una conversión real o se llama a un operador de conversión personalizado depende del tipo de tiempo de compilación de la expresión que se está emitiendo.

En su ejemplo, el tipo de tiempo de compilación de la expresión que se va a emitir, es decir. el tipo de expresión b es object el tipo object no tiene una conversión personalizada a cadena. Sin embargo, un molde podría ser válido y, por lo tanto, permitido por el compilador.

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

La cuarta línea será tratado como // llama a la funciton define como una conversión de encargo cadena d = MyString.op_implicit (a);

Lo mismo es cierto para la quinta línea. La quinta línea aunque utiliza la sintaxis para un molde no es un lanzamiento es una conversión.

Sin embargo, la tercera línea se ve como un elenco y es un elenco. Un reparto le está diciendo al compilador que tiene más información con respecto al tipo de tiempo de ejecución de un objeto que no tiene la compilación. (string)a le dice al compilador que puede estar seguro de que el objeto representado por a va a tener el tipo de cadena de tiempo de ejecución. En su caso, eso no es cierto, tiene el tipo MyString que no se deriva de la cadena (y no puede porque la cadena está sellada).

El punto es que a pesar de que las conversiones personalizadas (definidas mediante implícita o explícita) tienen la misma sintaxis que las versiones, son algo completamente diferente de un molde. Un elenco nunca se dejará la cadena de herencia (incluyendo interfaces heredan) se puede ir hacia arriba o abajo de la cadena con un reparto pero nunca dejarlo

4

operadores personalizada implícitos/explícitos sólo funcionan entre mecanografiadas valores - no object. Tal elenco siempre es un control de tipo básico o un unbox. La conversión implícita es:

string s = a; 
-1

debería probar:

public MyString:String 
{ 
//code 
} 
+1

cadena está sellada. – Jamiec

+0

oops :) sí, tienes razón – asd007

2

Usted puede tratar de cambiar la última línea a:

string c = (string)((MyString)b); 
Cuestiones relacionadas