2009-04-15 4 views
16

Jetzt gerade habe ich es mit Guid s.Kann Typ 'X' nicht implizit in 'String' umwandeln - wann und wie entscheidet es, dass es "nicht kann"?

Ich erinnere mich sicherlich, dass im ganzen Code an einigen Stellen diese implizite Konvertierung funktioniert, in anderen nicht. Bis jetzt sehe ich das Muster nicht.

Wie der Compiler entscheidet, wenn es nicht möglich ist? Ich meine, die Typmethode Guid.ToString() ist vorhanden, wird sie nicht aufgerufen, wenn diese Transformation benötigt wird?

Kann mir bitte jemand sagen, unter welchen Umständen diese Umwandlung automatisch erfolgt und wann ich explizit myInstance.ToString() anrufen muss?

+0

(Kommentar zur Frage hinzugefügt) –

+0

Versuch und Irrtum. Versuch und Irrtum. – Will

Antwort

32

Kurz gesagt, wenn es einen impliziten oder expliziten Umwandlungsoperator ist definiert:

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

Ich habe es nur selbst gesucht. Ich kann nicht glauben, dass ich dieses Ding in all den Jahren mit C# vermisst habe. Ich nehme an, ich brauchte es nie wirklich ... Danke, dass du mich heute etwas Neues lernen lässt. – User

+0

Und wo muss ich diesen Operator definieren? In der Type Klasse denke ich? Ich kann diesen WithImplicit- und WithExplicit-Klassen keine statischen Erweiterungen hinzufügen. – User

+0

Nein; Es gibt keinen Erweiterungsoperator. –

4

Der einzige Ort, wo man effektiv brauchen nicht ist, sich ToString() aufrufen, wenn Strings verketten.

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

Dann gibt es einige Situationen, in denen der Aufruf von .NET Framework, wie in String.Format() gemacht wird.

Ansonsten konvertiert der Compiler nur einen Typ, wenn bekannt ist, dass er kompatibel ist (z. B. Basisklasse oder Implementierung einer Schnittstelle oder über einen explizit codierten Konvertierungsoperator). Wenn Sie eine Umwandlung verwenden und der Compiler weiß, dass die Typen nicht kompatibel sein können (z. B. nicht in derselben Vererbungslinie und nicht in Schnittstellen), wird auch angegeben, dass sie nicht konvertiert werden kann. Das gleiche gilt für generische Typparameter.

+0

Nicht korrekt; Der Compiler berücksichtigt auch Konvertierungsoperatoren. In meinem Beitrag finden Sie Beispiele für sowohl implizite als auch explizite Konvertierungen, die * nicht * erfordern, dass der Aufrufer entweder ToString() oder String-Verkettung verwendet. –

+0

Sie haben Recht mit Conversion-Operatoren, aber ich vermeide sie normalerweise, deshalb habe ich sie hier nicht erwähnt.Ich werde meine Antwort ändern. – Lucero

4

Nein, es gibt keine implizite Konvertierung von GUID zu String, so dass es im Code überhaupt nicht funktioniert.

Es funktioniert nur, wenn es eine explizite Konvertierung gibt, aber die Konvertierung ist möglicherweise nicht sehr sichtbar. Zum Beispiel, wenn verketten Sie Strings:

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

Dieses wie eine implizite Konvertierung GUID-String aussehen, aber es ist nicht. Der Code, der erzeugt wird, sieht tatsächlich wie folgt aus:

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

Alle Operanden werden zu gieße vom Typ Object und in einem Array angeordnet. Die String.Concat Methode ruft dann die ToString Methode für jedes Element im Array auf, um die Zeichenfolgendarstellung für sie zu erhalten.

Verwandte Themen