當編譯器遇到方法調用時,所有參數的類型都是已知的,因爲C#是一種靜態類型語言:所有表達式和變量都是特定類型,且該類型是確定的並且在編譯時已知。
這是忽略dynamic
這稍微複雜的東西。
編輯:這是對您編輯的回覆。爲了清楚起見,我翻譯你的代碼如下:
interface IFoo { }
class Bar : IFoo { }
class Test {
public void DoWork(IFoo a) { }
public void DoWork(Bar b) { }
}
class Program {
static void Main(string[] args) {
IFoo a = new Bar();
Test t = new Test();
t.DoWork(a);
}
}
你問時爲t.DoWork(a)
在Main
調用該方法在這裏(Test.DoWork(IFoo)
或Test.DoWork(Bar)
)調用。答案是Test.DoWork(IFoo)
被調用。這基本上是因爲參數輸入爲IFoo
。讓我們去規範(§7.4.3.1):
的函數成員被認爲是適用的功能部件相對於當以下爲真參數列表答:
數A中的參數與函數成員聲明中的參數數量相同。
對於A中的每個參數,所述參數的參數傳遞模式(即,值,參考,或流出)等同於相應的參數的參數傳遞模式,並且
爲值參數或一個參數數組,參數存在從參數到相應參數或
的隱式轉換(第6.1節),對於ref或out參數,參數的類型與相應參數的類型相同。畢竟,ref或out參數是傳遞參數的別名。
此處的問題(請參閱粗體語句)是沒有從IFoo
到Bar
的隱式轉換。因此,方法Test.DoWork(Bar)
不是適用的功能成員。很明顯,Test.DoWork(IFoo)
是一個適用的函數成員,並且作爲唯一的選擇,編譯器將選擇它作爲調用的方法。