天天看點

C#自定義轉換(implicit 或 explicit)

  C#的類型轉換分為顯式轉換和隐式轉換,顯式轉換需要自己聲明轉換類型,而隐式轉換由編譯器自動完成,無需我們聲明,如:  

//long需要顯式轉換成int
    long l = 1L;
    int i = (int)l;

    //int可以隐式的轉換成long
    int i = 1;
    long l =;      

  我們還可以自定義顯式轉換和隐式轉換,分别采用 explicit 和 implicit 關鍵字來實作,格式:  

//顯式轉換
    public static explicit operator Type_A(Type_B b)
    {
        return Instance_Of_Type_A;
    }
    //隐式轉換
    public static implicit operator Type_A(Type_B b)
    {
        return Instance_Of_Type_A;
    }      

  其中 Type_A 和 Type_B 是不同的類型,且必須有一個類型是目前包含這個轉換的類型,如:  

public class ClassA
    {
        public string Description { get; set; }

        public static implicit operator ClassA(ClassB classB) => new ClassA() { Description = "implicit from ClassB to ClassA:" + classB.Description };
        public static implicit operator ClassA(string description) => new ClassA() { Description = "implicit from string to ClassA:" + description };
        public static implicit operator ClassB(ClassA classA) => new ClassB() { Description = "implicit from ClassA to ClassB:" + classA.Description };
        public static implicit operator string(ClassA classA) => "implicit from ClassA to string:" + classA.Description;

        public override string ToString() => Description;
    }
    public class ClassB
    {
        public string Description { get; set; }

        public static explicit operator ClassB(string description) => new ClassB() { Description = "explicit from string to ClassB:" + description };
        public static explicit operator string(ClassB classB) => "explicit from ClassB to string:" + classB.Description;

        public override string ToString() => Description;
    }
    static void Main(string[] args)
    {
        //隐式轉換
        {
            ClassA classA = "string";//字元串隐式轉換成ClassA
            Console.WriteLine(classA as object);

            string description = new ClassA() { Description = "ClassA" };//ClassA隐式轉換成字元串
            Console.WriteLine(description);

            ClassA classA1 = new ClassB() { Description = "ClassB" };//ClassB隐式轉換成ClassA
            Console.WriteLine(classA1 as object);

            ClassB classB = new ClassA() { Description = "ClassA" };//ClassA隐式轉換成ClassB
            Console.WriteLine(classB as object);

            //輸出:
            //implicit from string to ClassA:string
            //implicit from ClassA to string:ClassA
            //implicit from ClassB to ClassA:ClassB
            //implicit from ClassA to ClassB:ClassA
        }

        //顯式轉換
        {
            ClassB classB = (ClassB)"string";//字元串顯式轉換成ClassB
            Console.WriteLine(classB as object);

            string description = (string)new ClassB() { Description = "ClassB" };//ClassB顯式轉換成字元串
            Console.WriteLine(description);

            //輸出:
            //explicit from string to ClassB:string
            //explicit from ClassB to string:ClassB
        }
    }      

  注:自定義的轉換在開發中不常見,在一些第三方包、插件、架構中比較常見,但是有一個需要注意的點:is 和 as 運算不受自定義類型轉換的影響,如:

static void Main(string[] args)
    {
        //值類型int可以隐式轉換成long,==判斷為true,但是is判斷為false
        int i = 1;//int
        long l = i;//int可以隐式轉換為long
        Console.WriteLine(l == i);//true
        Console.WriteLine(i is long);//false

        ClassA classA = new ClassA() { Description = "ClassA" };
        ClassB classB = classA;//ClassA隐式轉換成ClassB
        Console.WriteLine(classB as object);//implicit from ClassA to ClassB:ClassA
        Console.WriteLine(classA is ClassB);//false
    }      

一個專注于.NetCore的技術小白