Freigeben über


Compilerfehler CS0029

Kann den Typ „type“ nicht implizit in „type“ konvertieren

Der Compiler erfordert eine explizite Konvertierung. Sie müssen z.B. einen r-Wert in den gleichen Typ wie einen l-Wert umwandeln. Oder Sie müssen zur Unterstützung bestimmter Operatorüberladungen Konvertierungsroutinen angeben.

Sie müssen Konvertierungen durchführen, wenn Sie eine Variablen eines Typs einer Variablen eines andere Typs zuweisen. Wenn Sie eine Zuweisung zwischen Variablen verschiedener Typen durchführen, muss der Compiler den Typ der rechten Seite des Zuweisungsoperator in den Typ der linken Seite des Zuweisungsoperators konvertieren. Nehmen Sie z.B. den folgenden Code:

int i = 50;
long lng = 100;
i = lng;

i = lng; führt eine Zuweisung durch, aber die Datentypen der Variablen auf der linken und der rechten Seite des Zuweisungsoperators stimmen nicht überein. Vor der Zuweisung konvertiert der Compiler implizit die Variable lng, die vom Typ „long“ ist, in den Typ „int“. Dies geschieht implizit, da kein Code den Compiler explizit angewiesen hat, diese Konvertierung durchzuführen. Das Problematische an diesem Code ist, dass dies als einschränkende Konvertierung angesehen, und der Compiler lässt keine einschränkenden Konvertierungen zu, da diese zu Datenverlusten führen könnte.

Eine einschränkende Konvertierung besteht, wenn Sie in einen Datentyp konvertieren, der weniger Speicherplatz im Arbeitsspeicher in Anspruch nimmt als der Datentyp, der konvertiert wird. Wenn Sie z.B. den Typ „long“ in den Typ „int“ konvertieren, wird dies als einschränkende Konvertierung angesehen. Der Typ „long“ nimmt 8 Byte Arbeitsspeicher in Anspruch, während ein Typ „int“ nur 4 Byte in Anspruch nimmt. Um zu sehen, wie es zu Datenverlust kommen kann, schauen Sie sich das folgende Beispiel an:

int i = 50;
long lng = 3147483647;
i = lng;

Die Variable lng enthält nun einen Wert, der nicht in der Variable i gespeichert werden kann, da er zu groß ist. Wenn Sie nun diesen Wert in den Typ „int“ konvertieren würden, würden Sie einige Ihrer Daten verlieren, und der konvertierte Wert wäre nicht der gleiche wie vor der Konvertierung.

Eine erweiternde Konvertierung ist das Gegenteil einer einschränkenden Konvertierung. Bei erweiternden Konvertierungen wird eine Konvertierung in einen Datentyp durchgeführt, der mehr Platz in Anspruch nimmt als der Typ, der konvertiert wird. Dies ist ein Beispiel für eine erweiternde Konvertierung:

int i = 50;
long lng = 100;
lng = i;

Beachten Sie den Unterschied zwischen diesem und dem ersten Codebeispiel. Dieses Mal befindet sich die Variable lng auf der rechten Seite des Zuweisungsoperators, sodass Sie das Ziel der Zuweisung darstellt. Vor der Zuweisung muss der Compiler die Variable i des Typ „int“ implizit in den Typ „long“ konvertieren. Dabei handelt es sich um eine erweiternde Konvertierung, da Sie einen Typ, der 4 Byte in Anspruch nimmt (int), in einen Typ, der 8 Byte in Anspruch nimmt (long), konvertieren. Implizite erweiternde Konvertierungen sind zulässig, da es dabei nicht zu Datenverlusten kommen kann. Jeder Wert, der in einem int-Typ gespeichert werden kann, kann auch in einem long-Typ gespeichert werden.

Sie wissen, dass implizite einschränkende Konvertierungen nicht zulässig sind. Deshalb müssen Sie den Datentyp explizit konvertieren, um diesen Code kompilieren zu können. Explizite Konvertierungen erfolgen durch eine Umwandlung. Umwandlung ist der in C# verwendete Begriff für die Konvertierung eines Datentyps in einen anderen. Damit der Code kompiliert, müssen Sie folgende Syntax verwenden.

int i = 50;
long lng = 100;
i = (int) lng;   // Cast to int.

Die dritte Codezeile weist den Compiler an, die Variable lng des Typs „long“ vor der Zuweisung explizit in den Typ „long“ zu konvertieren. Denken Sie daran, dass es bei einer einschränkenden Konvertierung zu Datenverlusten kommen kann. Einschränkende Konvertierungen sollten mit Vorsicht eingesetzt werden, und auch wenn der Code kompiliert, erhalten Sie möglicherweise zur Laufzeit unerwartete Ergebnisse.

Dies bezieht sich nur auf Werttypen. Wenn Sie mit Werttypen arbeiten, arbeiten Sie mit Daten, die direkt in der Variablen gespeichert sind. In .NET gibt es jedoch auch Verweistypen. Wenn Sie mit Verweistypen arbeiten, arbeiten Sie mit einem Verweis auf eine Variable und nicht mit den tatsächlichen Daten. Beispiele für Verweistypen sind Klassen, Schnittstellen und Arrays. Sie können einen Verweistyp weder explizit noch implizit in einen anderen konvertieren, es sei denn, der Compiler lässt die spezifische Konvertierung zu, oder die entsprechenden Konvertierungsoperatoren sind 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()
    {
        var myInt = new MyInt();
        int i = myInt; // CS0029
    }
}

Weitere Informationen