コンパイラ エラー CS0029

型 'type' を 'type' に暗黙的に変換できません

コンパイラでは、明示的な変換が必要です。 たとえば、左辺値と同じ型の右辺値をキャストする必要があります。 また、特定の演算子のオーバーロードをサポートするための変換ルーチンを指定する必要があります。

型の変数を別の型の変数に割り当てた場合、変換を行う必要があります。 異なる型の変数間で割り当て行うと、コンパイラで代入演算子の右辺の型を代入演算子の左辺の型に変換する必要があります。 次のコードを実行します。

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

i = lng; は割り当てを行いますが、代入演算子の左辺と右辺で変数のデータ型が一致しません。 割り当てを行う前に、コンパイラは long 型の変数 lng を暗黙的に int に変換しています。この変換の実行をコンパイラに明示的に指示するコードがないため、これは暗黙的です。 このコードの問題は、このコードが縮小変換と見なされ、データが失われる可能性があるため、コンパイラが暗黙的な縮小変換を許可しないことです。

変換元のデータ型よりもメモリに占める記憶域スペースが少ないデータ型に変換するときに、縮小変換が存在します。 たとえば、long を int に変換すると、縮小変換と見なされます。 long のメモリ占有スペースは 8 バイトですが、int の占有スペースは 4 バイトです。 データ損失の発生状況を確認するには、次のサンプルを参照してください。

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

変数 lng には、大きすぎるため変数 i に格納できない値が含まれています。 この値を int 型に変換しようとすると、データの一部が失われ、変換後の値は変換前の値とは同じになりません。

拡大変換は縮小変換の逆の処理です。 拡大変換では、変換元のデータ型よりもメモリに占める記憶域スペースが多いデータ型に変換します。 拡大変換の例を次に示します。

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

このコード サンプルと、最初のサンプルの違いに注意してください。 今回、変数 lng は代入演算子の左辺にあるため、割り当ての対象です。 割り当てを行う前に、コンパイラで int 型の変数 i は long 型に暗黙的に変換される必要があります。 メモリの占有スペースが 4 バイトの型 (int) をメモリの占有スペースが 8 バイトの型 (long) に変換するため、これは拡大変換です。 データ損失の可能性がないため、暗黙の拡大変換は許可されます。 int に格納できる値は、long にも格納できます。

前述のように、暗黙的な縮小変換は許可されないため、このコードをコンパイルできるようにするには、データ型を明示的に変換する必要があります。 明示的な変換にはキャストが使用されます。 キャストとは、あるデータ型を別のデータ型に変換する処理を示すために C# で使用される用語です。 コードをコンパイルするには、次の構文を使用する必要があります。

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

このコードの 3 行目では、割り当てを行う前に、long 型の変数 lng を int に明示的に変換するようにコンパイラに指示しています。 ただし、縮小変換にはデータ損失の可能性がある点に注意してください。 縮小変換を慎重に使用する必要があります。コードをコンパイルできるとしても、実行時に予期しない結果が発生する可能性があります。

この問題は値の型のみが対象です。 値の型を操作する場合、変数に格納されているデータを直接操作します。 ただし、.NET には参照型もあります。 参照型を操作する場合、実際のデータではなく、変数の参照を操作することになります。 参照型の例として、クラス、インターフェイス、および配列があります。 コンパイラが特定の変換を許可している場合、または適切な変換演算子が実装されている場合を除き、ある参照型を別の参照型に暗黙的または明示的に変換することはできません。

次の例では CS0029 が生成されます。

// 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
    }
}

関連項目