型別轉換關鍵字explicit與implicit的用法

型別轉換關鍵字explicit與implicit的用法

這篇是個語法文,雖然這兩個關鍵字比較陌生,但讓自己有個印象不是壞事

 

explicit 明確轉換與 implicit 隱含轉換都是c#內的關鍵字,目的是讓一個型別

轉換到另外一個型別,最常見的例子就是由double轉換到int時要使用明確轉換,

而int轉換到double的時候是使用隱含轉換。


double d = default(double);
int i = default(int);

//double 轉換為 int 時必須明確定義型別
//否則編譯器會丟出錯誤
i = (int)d;

//int 轉換為 double 時則可直接轉換
d = i;

為什麼會有這樣的區別呢?

是因為資料正確性的考量,當型別轉換時會有資料失真的問題時,一般使用明確

轉換,讓使用者可以明確的指定要轉換的型別並承擔風險。

 

使用時,要注意幾點

1. 必須是static

2. 使用implicit或explicit

3. 搭配operator(此也是c#關鍵字,可在類別或結構宣告內多載內建運算子或提供使用者定義的轉換)

4. 定義轉換型別

5. 傳入轉換的型別

 

類別定義


public class A
{
    private string _name;

    //將建構子設為私有,代表無法用new關鍵字new出A型別
    private A(string name)
    {
        _name = "Private Key" + name;
    }

    //隱含轉換 接受string型別
    public static implicit operator A(string expandedName)
    {
        return new A(expandedName);
    }

    //明確轉換,接受一個StringBuilder型別
    public static explicit operator A(StringBuilder expandedName)
    {
        return new A(expandedName.ToString());
    }

    public override string ToString()
    {
        return _name;
    }
}

Client使用


A a1 = "Hello a1";

Console.WriteLine(a1.ToString());

StringBuilder sb=new StringBuilder("Hello a2");

A a2 = (A)sb;

Console.WriteLine(a2.ToString());

image

語法的使用上大概是這個樣子,但這樣看還是沒什麼感覺,不知道何時該使用吧?

那接下來舉個.Net 內部的類別為例

在操作XML的時候,經常會使用Linq to XML,而其中有個類別是XElement

其建構式有五個多載:

image

可以看到第2、4、5的多載第一個參數是傳入一個XName型別的參數

XName是XML元素的名稱,如:<Books> 這樣代表一個XName,由於這個型別功能很簡單,

所以如果每次都要new XName("")傳進去似乎有點多此一舉(當然還有一點是跟XNamespace有關,但這邊不討論)

因此.Net 在設計時,將XName建構子的存取子設為internal,並且使用了implicit隱含轉換

image

如此一來在使用上就可以用下面這樣的方式叫用


var e = new XElement("Books");

 

在定義類別時,如果有需要,就可以使用這兩個關鍵字來提供類別一些額外的功能

但在使用時也必須考慮設計上是否合理

例如當兩類別有相關性時是否該提取出父類別或是介面來使用,而不是為了方便做了一堆轉換

導致程式撰寫與維護上的困難。