maxfie1d のブログ

マイクロソフト系技術ネタを中心に書きます。

C# の珍しいキーワード、implicit/explicit

C# を使っていて、滅多にお目にかからないキーワードが存在します。

前回の checked/unchecked キーワードに引き続き、 今回は implicit/explicit キーワードのお話です。

maxfie1d.hatenablog.com

implicit/explicit とは

C# では 「キャスト」が使えますが、暗黙的なキャストと明示的なキャストがあります。 implicitexplicitはキャストが行われる際にどのように値を変換するかを指定する場合に使います。

implicit の使い方の例

double 型の値をラップするだけのクラス Digit を定義します。 またdoubleDigit間を暗黙的に変換するメソッドを定義しています。

// See: https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/implicit

class Digit
{
    public Digit(double d) { val = d; }
    public double val;

    public static implicit operator double(Digit d)
    {
        return d.val;
    }

    public static implicit operator Digit(double d)
    {
        return new Digit(d);
    }
}

こうすることでdoubleDigit間を暗黙的に変換することが 可能になります。

// See: https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/implicit

class Program
{
    static void Main(string[] args)
    {
        Digit dig = new Digit(7);
        // これは 暗黙的な double オペレータを呼び出します
        //This call invokes the implicit "double" operator
        double num = dig;
        // これは 暗黙的な Digit オペレータを呼び出します
        Digit dig2 = 12;
        Console.WriteLine("num = {0} dig2 = {1}", num, dig2.val);
        Console.ReadLine();
    }
}

explicit の使い方の例

implicit と同様に型を変換するメソッドを定義してやります。

// See: https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/explicit

class Fahrenheit
{
    public Fahrenheit(float temp)
    {
        degrees = temp;
    }
    // Fahrenheit から Celsius へ明示的に変換します
    public static explicit operator Celsius(Fahrenheit fahr)
    {
        return new Celsius((5.0f / 9.0f) * (fahr.degrees - 32));
    }
    public float Degrees
    {
        get { return degrees; }
    }
    private float degrees;
}

class Celsius
{
    public Celsius(float temp)
    {
        degrees = temp;
    }
    public float Degrees
    {
        get { return degrees; }
    }
    private float degrees;
}

ただしimplicitとは違いexplicit明示的にキャストする必要があります。

// See: https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/explicit

class MainClass
{
    static void Main()
    {
        Fahrenheit fahr = new Fahrenheit(100.0f);
        Console.Write("{0} Fahrenheit", fahr.Degrees);
        Celsius c = (Celsius)fahr;

        Console.Write(" = {0} Celsius", c.Degrees);
    }
}