2009-04-15 23 views
16

Ahora mismo lo estoy teniendo con Guid s.No se puede convertir implícitamente el tipo "X" a "cadena": ¿cuándo y cómo decide que "no puede"?

Ciertamente recuerdo que a lo largo del código en algunos lugares esta conversión implícita funciona, en otros no. Hasta ahora no veo el patrón.

¿Cómo decide el compilador cuándo no puede? Quiero decir, el método de tipo Guid.ToString() está presente, ¿no se llama cuando se necesita esta transformación?

¿Puede alguien decirme en qué circunstancias esta transformación se realiza automáticamente y cuando tengo que llamar al myInstance.ToString() explícitamente?

+0

(se agregó un comentario a su pregunta) –

+0

Prueba y error. Prueba y error. – Will

Respuesta

32

En pocas palabras, cuando hay un operador de conversión implícita o explícita definida:

class WithImplicit { 
    public static implicit operator string(WithImplicit x) { 
     return x.ToString();} 
} 
class WithExplicit { 
    public static explicit operator string(WithExplicit x) { 
     return x.ToString(); } 
} 
class WithNone { } 

class Program { 
    static void Main() { 
     var imp = new WithImplicit(); 
     var exp = new WithExplicit(); 
     var none = new WithNone(); 
     string s1 = imp; 
     string s2 = (string)exp; 
     string s3 = none.ToString(); 
    } 
} 
+2

Acabo de buscarlo por mí mismo. No puedo creer que me haya perdido esta cosa en todos estos años con C#. Supongo que nunca lo necesité realmente ... Gracias por hacerme aprender algo nuevo hoy. – User

+0

¿Y dónde tengo que definir este operador? En la clase Type, supongo? No puedo agregar extensiones estáticas a estas clases WithImplicit y WithExplicit. – User

+0

No; no hay tal cosa como un operador de extensión. –

4

El único lugar donde efectivamente no es necesario llamar a ToString() cuando uno mismo es la concatenación de cadenas.

Guid g; 
int i; 
string s = "Hello "+g+' '+i; 

Entonces hay algunas situaciones en las que la llamada es hecha por el .NET Framework, como en String.Format().

Aparte de eso, el compilador solo convertirá un tipo si se sabe que es compatible (por ejemplo, la clase base o la implementación de una interfaz o mediante un operador de conversión codificado explícitamente). Cuando utiliza un molde y el compilador sabe que los tipos no pueden ser compatibles (por ejemplo, no en la misma línea de herencia y no en las interfaces), también indicará que no puede convertirlo. Lo mismo ocurre con los parámetros de tipo genérico.

+0

No es correcto; el compilador también respeta los operadores de conversión. Consulte mi publicación para ver ejemplos de conversiones implícitas y explícitas, que * no * requieren que la persona que llama use ToString() o cadena de concatenación. –

+0

Tiene razón acerca de los operadores de conversión, pero generalmente los evito, así que no los mencioné aquí.Cambiaré mi respuesta. – Lucero

4

No, no hay una conversión implícita de GUID a String, por lo que no funciona en absoluto en el código.

Solo funciona cuando hay una conversión explícita, pero la conversión puede no ser muy visible. Por ejemplo al concatenar cadenas:

string id = "--" + guidValue + " : " + num; 

Esto puede parecer una conversión implícita GUID-String, pero no lo es. El código que se genera en realidad se parece a esto:

string id = String.Concat(new object[] { "--", guidValue, " : ", num }); 

Todos los operandos se convierte en el tipo Object y se colocan en una matriz. El método String.Concat llama al método ToString para cada elemento de la matriz para obtener la representación de cadena para ellos.

Cuestiones relacionadas