Compilerfehler CS0029
Aktualisiert: November 2007
Fehlermeldung
Eine iImplizite Konvertierung vom Typ "Typ" zu "Typ" ist nicht möglich.
Cannot implicitly convert type 'type' to 'type'
Der Compiler benötigt eine explizite Konvertierung. So müssen Sie z. B. möglicherweise einen R-Wert in den Typ eines L-Werts umwandeln oder Konvertierungsroutinen zur Unterstützung bestimmter Operatorüberladungen zur Verfügung stellen.
Die Konvertierungen müssen stattfinden, wenn eine Variable eines Typs einer Variablen eines anderen Typs zugewiesen wird. Bei der Durchführung einer Zuweisung zwischen Variablen unterschiedlichen Typs muss der Compiler den Typ auf der rechten Seite des Zuweisungsoperators in den Typ auf der linken Seite des Zulassungsoperators konvertieren. Betrachten Sie den folgenden Code:
int i = 50;
long lng = 100;
i = lng;
i = lng; nimmt eine Zuweisung vor, die Datentypen der Variablen auf der linken und rechten Seite des Zuweisungsoperators stimmen jedoch nicht überein. Vor der Durchführung der Zuweisung konvertiert der Compiler die Variable lng des Typs long implizit in den Typ int. Diese Konvertierung erfolgt implizit, da der Compiler durch den Code nicht explizit zu der Konvertierung aufgefordert wurde. Das Problem mit diesem Code besteht darin, dass dies als einschränkende Konvertierung betrachtet wird, und der Compiler implizite einschränkende Konvertierungen nicht zulässt, da sie zu einem Datenverlust führen können.
Eine einschränkende Konvertierung liegt vor, wenn eine Konvertierung in einen Datentyp durchgeführt wird, der weniger Speicherplatz belegt als der Datentyp vor der Konvertierung. So wird beispielsweise die Konvertierung von long in int als einschränkende Konvertierung betrachtet. Ein long belegt 8 Bytes Speicherplatz, während ein int nur 4 Bytes belegt. Betrachten Sie folgendes Beispiel, um zu sehen, wie der Datenverlust auftreten kann:
int i = 50;
long lng = 3147483647;
i = lng;
Die Variable lng enthält jetzt einen Wert, der nicht in der Variablen i gespeichert werden kann, weil er zu umfangreich ist. Wenn wir diesen Wert in einen int-Typ konvertieren müssten, würde ein Teil der Daten verloren gehen, und der konvertierte Wert würde nicht mit dem vor der Konvertierung vorliegenden Wert übereinstimmen.
Das Gegenstück zu einer einschränkenden Konvertierung wäre eine erweiternde Konvertierung. Eine erweiternde Konvertierung liegt vor, wenn eine Konvertierung in einen Datentyp durchgeführt wird, der mehr Speicherplatz belegt als der vor der Konvertierung vorliegende Datentyp. Es folgt ein Beispiel für eine erweiternde Konvertierung:
int i = 50;
long lng = 100;
lng = i;
Beachten Sie den Unterschied zwischen diesem und dem vorhergehenden Codebeispiel. Diesmal befindet sich die Variable lng auf der linken Seite des Zuweisungsoperators, sie ist jetzt also das Ziel unserer Zuweisungsoperation. Bevor die Zuweisung stattfinden kann, muss der Compiler die Variable I vom Typ int implizit konvertieren. Hierbei handelt es sich um eine erweiternde Konvertierung, da die Konvertierung ausgehend von einem Typ, der 4 Bytes Speicherplatz belegt (int), in einen Typ erfolgt, der 8 Bytes belegt (long). Implizite erweiternde Konvertierungen sind zulässig, da es nicht zu Datenverlusten kommen kann. Jeder beliebige Wert, der in einem int gespeichert werden kann, kann auch in einem long gespeichert werden.
Implizite einschränkende Konvertierungen sind nicht zulässig, um diesen Code kompilieren zu können, müssen wir also den Datentyp explizit konvertieren. Explizite Konvertierungen werden unter Verwendung der Umwandlung durchgeführt. In C# beschreibt der Begriff Umwandlung das Konvertieren eines Datentyps in einen anderen. Damit der Code kompiliert werden kann, müssen wir die folgende Syntax verwenden:
int i = 50;
long lng = 100;
i = (int) lng; // cast to int
Eine dritte Codezeile weist den Compiler an, die Variable lng des Typs long explizit in den Typ Int zu konvertieren, bevor die Zuweisung durchgeführt wird. Bei einschränkenden Konvertierungen kann es, wie bereits erwähnt, zu Datenverlusten kommen. Einschränkende Konvertierungen sollten daher mit Bedacht verwendet werden. Auch wenn der Code kompiliert werden kann, kann es zur Laufzeit doch zu unerwarteten Ergebnissen kommen.
Bei dieser Erörterung wurden nur Werttypen berücksichtigt. Beim Arbeiten mit Werttypen arbeiten Sie direkt mit den in der Variablen gespeicherten Daten. .NET Framework verfügt jedoch auch über Referenztypen. Beim Arbeiten mit Referenztypen arbeiten Sie mit Verweisen auf eine Variable, nicht jedoch mit den Daten selbst. Beispiele für Referenztypen sind Klassen, Schnittstellen und Arrays. Es ist nicht möglich, einen Referenztyp implizit oder explizit in einen anderen zu konvertieren, es sei denn, der Compiler unterstützt die spezifische Konvertierung oder die geeigneten Konvertierungsoperatoren wurden implementiert.
Im folgenden Beispiel wird CS0029 generiert:
// CS0029.cs
public class MyInt
{
private int x = 0;
// Uncomment this conversion routine to resolve CS0029
/*
public static implicit operator int(MyInt i)
{
return i.x;
}
*/
public static void Main()
{
MyInt myInt = new MyInt();
int i = myInt; // CS0029
}
}