自訂型別轉換運算子 (user-defined type conversion operator)

 

一、explicit 明確轉型

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Celsius c1 = new Celsius(5f);
            Console.Write($"{c1.Degrees} Celsius");
            Fahrenheit f1 = (Fahrenheit)c1;
            Console.WriteLine($" = {f1.Degrees} Fahrenheit");

            Fahrenheit f2 = new Fahrenheit(100.0f);
            Console.Write($"{f2.Degrees} Fahrenheit");
            Celsius c2 = (Celsius)f2;
            Console.WriteLine($" = {c2.Degrees} Celsius");

            Console.ReadKey();
        }
    }

    // 1度C等於1.8度F
    class Celsius
    {
        public Celsius(float temp)
        {
            Degrees = temp;
        }

        public float Degrees { get; }
    }

    class Fahrenheit
    {
        public Fahrenheit(float temp)
        {
            Degrees = temp;
        }

        public float Degrees { get; }

        // convert celsius to fahrenheit
        public static explicit operator Fahrenheit(Celsius c)
        {
            return new Fahrenheit((9.0f / 5.0f) * c.Degrees + 32);
        }

        // convert fahrenheit to celsius
        public static explicit operator Celsius(Fahrenheit fahr)
        {
            return new Celsius((5.0f / 9.0f) * (fahr.Degrees - 32));
        }
    }
}

說明:

明確轉型方法可以放在來源類別或是目地類別皆可。

 

二、implicit 隱含轉型

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Digit dig = new Digit(7);
            //This call invokes the implicit "double" operator
            double num = dig;
            //This call invokes the implicit "Digit" operator
            Digit dig2 = 12;
            Console.WriteLine("num = {0} dig2 = {1}", num, dig2.val);

            Console.ReadKey();
        }
    }

    class Digit
    {
        public Digit(double d) { val = d; }
        public double val;
        // ...other members

        // User-defined conversion from Digit to double
        public static implicit operator double(Digit d)
        {
            return d.val;
        }
        //  User-defined conversion from double to Digit
        public static implicit operator Digit(double d)
        {
            return new Digit(d);
        }
    }
}

 

三、operator 運算子多載

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Fraction a = new Fraction(1, 2);
            Fraction b = new Fraction(3, 7);
            Fraction c = new Fraction(2, 3);
            Console.WriteLine((double)(a * b + c));

            Console.ReadKey();
        }
    }

    class Fraction
    {
        int num, den;
        public Fraction(int num, int den)
        {
            this.num = num;
            this.den = den;
        }

        // overload operator +
        public static Fraction operator +(Fraction a, Fraction b)
        {
            return new Fraction(a.num * b.den + b.num * a.den,
               a.den * b.den);
        }

        // overload operator *
        public static Fraction operator *(Fraction a, Fraction b)
        {
            return new Fraction(a.num * b.num, a.den * b.den);
        }

        // user-defined conversion from Fraction to double
        public static implicit operator double(Fraction f)
        {
            return (double)f.num / f.den;
        }
    }
}

說明:

上面範例為利用 operator 關鍵字來多載運算子。

 

參考資料:

explicit (C# Reference)

implicit (C# Reference)

operator (C# Reference)

Overloadable operators (C# Programming Guide)