キャストと型変換 (C# プログラミング ガイド)Casting and Type Conversions (C# Programming Guide)

C# はコンパイル時 (変数が宣言された後) に静的に型指定されるため、その型が変数の型に暗黙的に変換可能でない限り、再び宣言したり、別の型の値を代入したりすることはできません。Because C# is statically-typed at compile time, after a variable is declared, it cannot be declared again or assigned a value of another type unless that type is implicitly convertible to the variable's type. たとえば、stringint に暗黙的に変換することはできません。For example, the string cannot be implicitly converted to int. そのため、次のコードに示すように、iint として宣言した後、"Hello" という文字列を代入することはできません。Therefore, after you declare i as an int, you cannot assign the string "Hello" to it, as the following code shows:

int i;  
i = "Hello"; // error CS0029: Cannot implicitly convert type 'string' to 'int'

しかし場合によっては、別の型の変数やメソッドのパラメーターに値をコピーする必要が生じることもあります。However, you might sometimes need to copy a value into a variable or method parameter of another type. たとえば、パラメーターが double として型指定されたメソッドに、整数の変数を渡す必要が生じることもあるでしょう。For example, you might have an integer variable that you need to pass to a method whose parameter is typed as double. また、クラス変数をインターフェイス型の変数に代入しなければならない場合もあるかもしれません。Or you might need to assign a class variable to a variable of an interface type. この種の操作は、型変換と呼ばれます。These kinds of operations are called type conversions. C# では、次のような変換を実行できます。In C#, you can perform the following kinds of conversions:

  • 暗黙的な変換: この変換はタイプ セーフであり、データが失われることはないため、特別な構文は必要ありません。Implicit conversions: No special syntax is required because the conversion is type safe and no data will be lost. 例としては、小さい整数型から大きい整数型への変換や、派生クラスから基底クラスへの変換が挙げられます。Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.

  • 明示的な変換 (キャスト): 明示的な変換には、キャスト演算子が必要です。Explicit conversions (casts): Explicit conversions require a cast operator. 変換時に情報が失われる可能性がある場合や、その他の理由によって変換が成功しない可能性がある場合には、キャストが必要です。Casting is required when information might be lost in the conversion, or when the conversion might not succeed for other reasons. 典型的な例としては、より精度の低い型 (または、より範囲が狭い型) に数値を変換する場合や、基底クラスのインスタンスを派生クラスに変換する場合が挙げられます。Typical examples include numeric conversion to a type that has less precision or a smaller range, and conversion of a base-class instance to a derived class.

  • ユーザー定義の変換: ユーザー定義の変換は特殊なメソッドによって実行されます。これを定義することで、基本クラスと派生クラスの関係がないカスタム型間の明示的および暗黙的な変換が可能になります。User-defined conversions: User-defined conversions are performed by special methods that you can define to enable explicit and implicit conversions between custom types that do not have a base class–derived class relationship. 詳しくは、「変換演算子」をご覧ください。For more information, see Conversion Operators.

  • ヘルパー クラスを使用する変換: 整数と System.DateTime オブジェクトの間、16 進文字列とバイト配列の間など、互換性のない型の間で変換を行うには、System.BitConverter クラス、System.Convert クラス、および組み込み数値型の Parse メソッド (Int32.Parse など) を使用できます。Conversions with helper classes: To convert between non-compatible types, such as integers and System.DateTime objects, or hexadecimal strings and byte arrays, you can use the System.BitConverter class, the System.Convert class, and the Parse methods of the built-in numeric types, such as Int32.Parse. 詳細については、「方法 :バイト配列を int に変換する」、「方法: 文字列を数値に変換する」、および「方法: 16 進文字列と数値型の間で変換する」をご覧ください。For more information, see How to: Convert a byte Array to an int, How to: Convert a String to a Number, and How to: Convert Between Hexadecimal Strings and Numeric Types.

暗黙の型変換Implicit Conversions

組み込みの数値型の場合、格納される値を切り捨てたり丸めたりしなくても変数に収めることができるのであれば、暗黙的な変換を実行できます。For built-in numeric types, an implicit conversion can be made when the value to be stored can fit into the variable without being truncated or rounded off. たとえば、long 型の変数 (64 ビットの整数) は、int (32 ビットの整数) が格納できる任意の値を格納できます。For example, a variable of type long (64-bit integer) can store any value that an int (32-bit integer) can store. 次の例の場合、コンパイラは右側の num の値を bigNum に代入する前に、この値を long 型へと暗黙的に変換します。In the following example, the compiler implicitly converts the value of num on the right to a type long before assigning it to bigNum.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

暗黙的な数値変換をすべてまとめた一覧については、「暗黙的な数値変換の一覧表」をご覧ください。For a complete list of all implicit numeric conversions, see Implicit Numeric Conversions Table.

参照型の場合は、特定のクラスから、その直接または間接的な基底クラスやインターフェイスに対して、常に暗黙的な変換が存在します。For reference types, an implicit conversion always exists from a class to any one of its direct or indirect base classes or interfaces. 派生クラスには常に基底クラスのすべてのメンバーが含まれるため、特別な構文は必要ありません。No special syntax is necessary because a derived class always contains all the members of a base class.

Derived d = new Derived();  
Base b = d; // Always OK.  

明示的変換Explicit Conversions

変換によって情報が失われるリスクがある場合は、コンパイラで明示的な変換を実行する必要があります。これをキャストと呼びます。However, if a conversion cannot be made without a risk of losing information, the compiler requires that you perform an explicit conversion, which is called a cast. キャストとは、変換を行う意図があることと、データ損失が発生する可能性があることを、コンパイラに明示的に知らせるための方法です。A cast is a way of explicitly informing the compiler that you intend to make the conversion and that you are aware that data loss might occur. キャストを実行するには、変換する値または変数の前に、キャストする型をかっこで囲んで指定します。To perform a cast, specify the type that you are casting to in parentheses in front of the value or variable to be converted. 次のプログラでは、doubleint にキャストしています。このプログラムは、キャストなしではコンパイルされません。The following program casts a double to an int. The program will not compile without the cast.

class Test
{
    static void Main()
    {
        double x = 1234.7;
        int a;
        // Cast double to int.
        a = (int)x;
        System.Console.WriteLine(a);
    }
}
// Output: 1234

許可される明示的数値変換の一覧については、「明示的な数値変換の一覧表」をご覧ください。For a list of the explicit numeric conversions that are allowed, see Explicit Numeric Conversions Table.

参照型の場合は、基本型から派生型に変換する必要がある場合に、明示的なキャストが必要です。For reference types, an explicit cast is required if you need to convert from a base type to a derived type:

// Create a new derived type.  
Giraffe g = new Giraffe();  
  
// Implicit conversion to base type is safe.  
Animal a = g;  
  
// Explicit conversion is required to cast back  
// to derived type. Note: This will compile but will  
// throw an exception at run time if the right-side  
// object is not in fact a Giraffe.  
Giraffe g2 = (Giraffe) a;  

参照型の間でキャスト操作を行っても、基になるオブジェクトの実行時の型は変わりません。そのオブジェクトへの参照として使用される値の型だけが変更されます。A cast operation between reference types does not change the run-time type of the underlying object; it only changes the type of the value that is being used as a reference to that object. 詳しくは、「ポリモーフィズム」をご覧ください。For more information, see Polymorphism.

実行時に発生する型変換の例外Type Conversion Exceptions at Run Time

一部の参照型変換では、キャストが有効になるかどうかをコンパイラで判断できません。In some reference type conversions, the compiler cannot determine whether a cast will be valid. キャスト操作が正しくコンパイルされても、実行時に失敗する可能性があります。It is possible for a cast operation that compiles correctly to fail at run time. 次の例に示すように、型キャストが実行時に失敗すると、InvalidCastException がスローされます。As shown in the following example, a type cast that fails at run time will cause an InvalidCastException to be thrown.


using System;

class Animal
{
    public void Eat() { Console.WriteLine("Eating."); }
    public override string ToString()
    {
        return "I am an animal.";
    }
}
class Reptile : Animal { }
class Mammal : Animal { }

class UnSafeCast
{
    static void Main()
    {            
        Test(new Mammal());

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }

    static void Test(Animal a)
    {
        // Cause InvalidCastException at run time 
        // because Mammal is not convertible to Reptile.
        Reptile r = (Reptile)a;
    }

}

C# では、キャストの実行前に互換性をテストできるよう、is 演算子と as 演算子が提供されています。C# provides the is and as operators to enable you to test for compatibility before actually performing a cast. 詳細については、「方法 :パターン マッチング、as 演算子、is 演算子を使用して安全にキャストする」をご覧ください。For more information, see How to: Safely cast using pattern matching, as and is Operators.

C# 言語仕様C# Language Specification

詳細については、「C# 言語の仕様」を参照してください。For more information, see the C# Language Specification. 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。The language specification is the definitive source for C# syntax and usage.

参照See Also