[C#] as 與 強制轉型差異

  • 193
  • 0

.as 與 強制轉型差異

強制轉型

object member = "TEST";
DateTime result = (DateTime) member;

上述程式碼編譯成功,但執行時會拋出例外錯誤。

Unable to cast object of type 'System.String' to type 'System.DateTime'.


AS轉型

object member = "TEST";
DateTime result = member as DateTime;

上述編譯會錯誤

CS0077 The as operator must be used with a reference type or nullable type ('DateTime' is a non-nullable value type)

as 運算子必須搭配參考類型或可為 Null 的類型一起使用 ('DateTime' 是不可為 Null 的實值類型)


object member = "TEST";
DateTime? result = member as DateTime?;

上述編譯成功且運行時不會拋出例外錯誤,但result會是NULL因為無法轉型成功。


進階應用

explicit、implicit與operator關鍵字

explicit:

關鍵字會宣告必須以轉型 (cast) 叫用的使用者定義型別轉換運算子。

implicit :

關鍵字是用來宣告隱含的使用者定義型別轉換運算子。 使用它可啟用使用者定義型別和其型別之間的隱含轉換,但前提是要保證轉換作業不會導致資料的遺失。

operator:

關鍵字可在類別或結構 (Struct) 宣告內多載內建運算子或提供使用者定義的轉換。

實作轉換方法有幾個限制

  • 存取修飾詞必須是 public
  • 必須是靜態方法(static)
  • 必須有 implicit 或 explicit 關鍵字
  • 必須有 operator 關鍵字
void Main()
{
    StringBuilder sb = new StringBuilder ("Hello World");

    MyString str1 = "123 ";     //隱含轉型,將String轉成MyString。

    string x1 = str1;           //隱含轉型,將MyString轉成String。

    MyString s2 = (MyString)sb; //明確轉型,將StringBuilder轉成MyString。
}
class MyString
{
    private string _Value;

    private MyString (string value)
    {
        _Value = value.Trim();
    }

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

    //隱含轉換 接受MyString型別,回傳string型別
    public static implicit operator string (MyString me)
    {
        return me._Value;
    }

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