我們在這裡可以假設一下:假如存在一個類A是String類的派生類(實際上 string類是sealed的,也就是不可繼承的,所以我說了是假設),並且存在在上面的代碼改 變如下:
using System;
public class Program
{ public static void Main()
{
Show(null);
Show ("");
}
static void Show(Object o)
{
Console.WriteLine("Object");
}
static void Show (String s)
{
Console.WriteLine("String");
}
static void Show(A a)//假設A是String的派生類,當然實際上String類並沒有 派生類,這裡僅僅是假設
{
Console.WriteLine("A");
}
}
如果上面的假設成立,上面的代碼運行結果應該如下:
A
String
(3)為什麼Show(1)會調用static void Show(Object o)這個 方法呢?在這個類中與Show(1)最精確的方法重載應該是static void Show(int i)這種方法 聲明,但是方法中沒有,因為int是繼承自ValueType類,所以如果沒有static void Show (int i)這種聲明,那麼其次接近的聲明應該是static void Show(ValueType v)這種聲明, 可惜方法中依然沒有,不過ValueType類繼承自Object類,所以比static void Show (ValueType v)還次一點的方法重載聲明應該是static void Show(Object o),而類中也確實 存在這種聲明,所以會調用static void Show(Object o)這個方法。當然從int到Object這個 過程中存在一次box,也就是裝箱(裝箱是從值類型到引用類型的轉換),這個可以從下面的 IL代碼可以看出來。
以下是第二種情況下Main()方法的IL代碼:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代碼大小 32 (0x20)
.maxstack 8
IL_0000: nop
IL_0001: ldnull
IL_0002: call void OverrideDemo.Program::Show(string)
IL_0007: nop
IL_0008: ldstr ""
IL_000d: call void OverrideDemo.Program::Show(string)
IL_0012: nop
IL_0013: ldc.i4.1
IL_0014: box [mscorlib]System.Int32
IL_0019: call void OverrideDemo.Program::Show(object)
IL_001e: nop
IL_001f: ret
} // end of method Program::Main