假設我們定義了兩個類別,分別是攝氏溫度類別與華氏溫度類別,雖然我們可以在溫度類別中建立一個方法來轉型
攝氏 c = new 攝氏("37.5");
華氏 f = c.轉型成華氏();
但若我們希望能像如下進行型別轉換,我們可以實作轉型運算子。
攝氏 c = new 攝氏("37.5");
華氏 f = (華氏) c;
這兩個類別都是各自獨立的,我把溫度封裝在裡面,修改溫度的方式只有初始化類別時與使用調整溫度方法這兩個方式,並只有使用讀取溫度方法才能拿到類別中的溫度。
基礎架構如以下:
class 攝氏
{
private double 溫度;
public 攝氏(double 初始溫度){
}
public void 調整溫度(double 設定值){
}
public string 讀取溫度(){
}
}
實際上,初始化使可能會傳入double或字串,所以我的建構式可能有兩種,還要實作攝氏與華氏兩個類別的程式碼,實作結果如下:
class 攝氏
{
private double 溫度;
public 攝氏(double 初始溫度)
{
溫度 = 初始溫度;
}
public 攝氏(string 初始溫度)
{
溫度 = double.Parse(初始溫度);
}
public void 調整溫度(double 設定值)
{
溫度 = 設定值;
}
public string 讀取溫度()
{
string 溫度C = 溫度.ToString() + "ºC";
return 溫度C;
}
}
class 華氏
{
private double 溫度;
public 華氏(double 初始溫度)
{
溫度 = 初始溫度;
}
public 華氏(string 初始溫度)
{
溫度 = double.Parse(初始溫度);
}
public void 調整溫度(double 設定值)
{
溫度 = 設定值;
}
public string 讀取溫度()
{
string 溫度F = 溫度.ToString() + "ºF";
return 溫度F;
}
}
現在就可以開始用operator關鍵字製作自己的轉型運算子,這邊我要做明確轉型的運算子,那就要用explicit關鍵字,另外規定轉型運算子要設定成static,讓程式執行前準備好運算子,免得要轉型時還沒建立物件,另外,特別的地方在於運算子可以寫在兩個物件任一方,C#會在欲轉型與被轉型兩方尋找轉換運算子
class 華氏
{
...省略先前內容...
public static explicit operator 華氏(攝氏 c)
{
string 攝氏溫度 = c.讀取溫度();
string[] 分割 = 攝氏溫度.Split('º');
double 溫度轉換 = double.Parse(分割[0]) / 5 * 9 + 32;
華氏 f = new 華氏(溫度轉換);
return f;
}
}
class 攝氏
{
...省略先前內容...
public static explicit operator 攝氏(華氏 f)
{
string 華氏溫度 = f.讀取溫度();
string[] 分割 = 華氏溫度.Split('º');
double 溫度轉換 = (double.Parse(分割[0]) - 32) / 9 * 5;
攝氏 c = new 攝氏(溫度轉換);
return c;
}
}
我們可以寫個小程式觀看實作結果
static void Main(string[] args)
{
攝氏 c = new 攝氏(37.5);
Console.WriteLine(c.讀取溫度());
華氏 f = (華氏)c;
Console.WriteLine(f.讀取溫度());
c = (攝氏)f;
Console.WriteLine(c.讀取溫度());
Console.ReadKey();
}
我們可以使用System命名空間,提供的Convert類別裡面的轉型方法進行轉型。例如以下:
int i = System.Convert.ToInt32("12345");
可以從https://referencesource.microsoft.com
看到Convert實作的原始碼,有些方法也是直接使用轉型運算子。
繼承轉型是CLR在背後幫我們依繼承關係自動轉型,而非轉型計算子,例如:
int i = 123;
object o = i; //CLR幫我們自動轉型成object;
int j = (int) o //需明確告知CLR欲轉成哪個object子型別,此轉換是依靠CLR而非轉型運算子
又例如以下,B繼承於A:
class A
{
public int numberA;
}
class B : A
{
public int numberB;
}
當物件B,在宣告為A或object,CLR會幫我們自動轉型。
object o1 = new B();
A o2 = new B();
若要把宣告為A的物件o2轉回為B,則需明確告知CLR
B o3 = (B) o2;
以下為例,字串+整數時,整數會被轉換成object