2009-04-15 21 views
16

In questo momento sto avendo con Guid s.Non è possibile convertire in modo implicito il tipo "X" in "stringa" - quando e in che modo decide che "non può"?

Ricordo certamente che in tutto il codice in alcuni punti questa conversione implicita funziona, in altri no. Fino ad ora non riesco a vedere il modello.

Come decide il compilatore quando non è possibile? Voglio dire, il metodo tipo Guid.ToString() è presente, non viene chiamato ogni volta che questa trasformazione è necessaria?

Qualcuno può dirmi in quali circostanze questa trasformazione viene eseguita automaticamente e quando devo chiamare esplicitamente myInstance.ToString()?

+0

(commento aggiunto re la tua domanda) –

+0

Prova ed errore. Prova ed errore. – Will

risposta

32

In breve, quando v'è una implicita o esplicita operatore di conversione definiti:

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

Ho appena controllato. Non posso credere di aver perso questa cosa in tutti questi anni con C#. Suppongo che non ne abbia mai avuto bisogno davvero ... Grazie per avermi fatto imparare qualcosa di nuovo oggi. – User

+0

E dove devo definire questo operatore? Nella classe di tipo, immagino? Non riesco ad aggiungere estensioni statiche a queste classi WithImplicit e WithExplicit. – User

+0

No; non esiste un operatore di estensione. –

4

L'unico posto dove si effettivamente non è necessario chiamare ToString() te è quando concatenazione di stringhe.

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

Poi ci sono alcuni casi in cui la chiamata viene effettuata da .NET Framework, come nel String.Format().

Oltre a ciò, il compilatore converte un tipo solo se è noto che sia compatibile (ad esempio classe di base o implementazione di un'interfaccia o tramite un operatore di conversione esplicitamente codificato). Quando si utilizza un cast e il compilatore sa che i tipi non possono essere compatibili (ad esempio non nella stessa linea di ereditarietà e non nelle interfacce), dirà anche che non può convertirlo. Lo stesso vale per i parametri di tipo generico.

+0

Non corretto; il compilatore rispetta anche gli operatori di conversione. Vedere il mio post per esempi di conversioni implicite ed esplicite, che * non * richiedono al chiamante di utilizzare ToString() o concatenazione di stringhe. –

+0

Hai ragione sugli operatori di conversione, ma di solito li evito quindi non li ho menzionati qui.Cambierò la mia risposta – Lucero

4

No, non c'è conversione implicita da GUID a String, in modo che non funzioni affatto nel codice.

Funziona solo dove esiste una conversione esplicita, ma la conversione potrebbe non essere molto visibile. Per esempio quando si concatenare le stringhe:

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

Questo può sembrare una conversione implicita GUID-String, ma non lo è. Il codice che genera effettivamente assomiglia a questo:

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

Tutti gli operandi sono espressi al tipo Object e collocati in una matrice. Il metodo String.Concat chiama quindi il metodo ToString per ciascun elemento nell'array per ottenere la rappresentazione di stringa per tali elementi.

Problemi correlati