首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 隱式與顯式轉換運算符:implicit 與 explicit 關鍵字深度解析

     編輯:關於C語言

核心差異一覽

關鍵字轉換類型語法適用場景
implicit隱式轉換Target t = source;資訊不遺失、語意自然、無例外風險
explicit顯式轉換Target t = (Target)source;可能遺失精度、範圍縮減、語意需強調意圖

經典範例:神仙與妖怪互轉

using System;

class Program {
    class Immortal {
        public string Name;
        public Immortal(string name) => Name = name;
        // 隱式:神仙 → 妖怪(下凡無風險)
        public static implicit operator Monster(Immortal value)
            => new Monster($"{value.Name}:神仙變妖怪?偷偷下凡即可。。。");
    }

    class Monster {
        public string Name;
        public Monster(string name) => Name = name;
        // 顯式:妖怪 → 神仙(需修煉五百年,強調意圖)
        public static explicit operator Immortal(Monster value)
            => new Immortal($"{value.Name}:妖怪想當神仙?再去修煉五百年!");
    }

    static void Main() {
        Immortal immortal = new Immortal("紫霞仙子");
        Monster monster1 = immortal;           // 隱式轉換
        Console.WriteLine(monster1.Name);

        Monster monster2 = new Monster("孫悟空");
        Immortal immortal2 = (Immortal)monster2; // 顯式轉換
        Console.WriteLine(immortal2.Name);

        Console.ReadLine();
    }
}

輸出結果

紫霞仙子:神仙變妖怪?偷偷下凡即可。。。
孫悟空:妖怪想當神仙?再去修煉五百年!

內建型別對照

來源目標轉換關鍵字
intlong擴大implicit
longint縮減explicit
doublefloat精度遺失explicit
DerivedBase向上轉型implicit
BaseDerived向下轉型explicit

自訂轉換運算子規則

  • 必須是 public static
  • 來源或目標型別必須包含運算子定義的類別(雙向至少一方)
  • 不能轉換為 object、介面型別、基底類別(已有內建轉換)
  • implicit 與 explicit 不能針對同一對型別雙向定義(會衝突)
  • 轉換運算子不支援多型:Base b = new Derived(); Target t = (Target)b; 若 Target 只定義 explicit operator Target(Derived) 會編譯錯誤

實務設計指南

  1. 預設用 implicit:若轉換總是安全、無副作用、語意清晰(如 Wrapper → Value、Dto → Entity 簡單映射)。
  2. 謹慎用 explicit:可能拋例外、遺失資料、語意上需呼叫端明確確認(如 double → int、string → DateTime 解析)。
  3. 避免過度使用:隱式轉換鏈(A→B→C)會導致難以追蹤的型別推斷錯誤;複雜映射改用 MapTo() 方法或 AutoMapper。
  4. 文檔化:XML 註解標註轉換條件、可能例外、資料遺失說明。

進階:使用者定義轉換與多型


class Base { }
class Derived : Base { }
class Target {
    public static explicit operator Target(Derived d) => new Target(); // 僅接受 Derived
}
Base b = new Derived();
Target t = (Target)b; // 編譯錯誤:無適用轉換(b 編譯時型別為 Base)
Target t2 = (Target)(Derived)b; // 需雙重轉型

此限制是為了型別安全,避免執行時意外失敗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved