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

C# 方法重載解析(二):引用類型與實例類型的區別

     編輯:關於C語言

引言

上一篇我們討論了 null 的匹配行為。本文通過一個具體例子,進一步揭示 C# 重載解析時依據的是變量的聲明類型(引用類型),而非對象的實際運行時類型(實例類型)。

代碼示例

using System;

namespace OverrideDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            String s = null;
            Show(s);          // 調用 Show(string)

            Object o = "123";
            Show(o);          // 調用 Show(object)
        }

        static void Show(string s) { Console.WriteLine("String"); }
        static void Show(Object o) { Console.WriteLine("Object"); }
    }
}

運行結果

String
Object

IL 代碼佐證

.method private hidebysig static void Main(string[] args) cil managed
{
  .entrypoint
  .maxstack 1
  .locals init ([0] string s, [1] object o)
  IL_0000: nop
  IL_0001: ldnull
  IL_0002: stloc.0
  IL_0003: ldloc.0
  IL_0004: call void OverrideDemo.Program::Show(string)
  IL_0009: nop
  IL_000a: ldstr "123"
  IL_000f: stloc.1
  IL_0010: ldloc.1
  IL_0011: call void OverrideDemo.Program::Show(object)
  IL_0016: nop
  IL_0017: ret
}

核心結論

1. 精確匹配靜態類型

String s = null; 中 s 的聲明類型是 string,雖然運行時值為 null,但編譯器根據靜態類型選擇 Show(string)。這證明重載解析在編譯期完成,依賴變量的靜態類型。

2. 引用類型決定調用,而非實例類型

Object o = "123"; 這裡 o 的聲明類型是 object,雖然它引用一個 string 實例,但調用的是 Show(object)。說明 C# 不 根據對象的實際類型(實例類型)進行重載分發,這與虛擬方法的多態行為不同。

對比:虛擬方法 vs 重載方法

特性虛擬方法重載方法
分發時機運行時編譯時
依據實例類型聲明(引用)類型
關鍵字virtual/override無特殊關鍵字

實務建議

  • 避免在重載簽名中使用基類與派生類參數並存,易造成誤解。
  • 若需根據運行時類型分發,請使用多態(虛擬方法)或模式匹配(C# 7+)。
  • 閱讀 IL 可幫助理解編譯器的綁定決策。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved