如果牽扯到可變數量的引數,那麼帶有可變數量引數的方法,和普通方法不同。C# 會優先呼叫普通方法。例如:注意:由或不由 ref/out 修飾,在編譯器眼中是一樣的。
public void NormalMethod(int a,params int[] b) { Console.WriteLine("2"); } public void NormalMethod(int a, intb) { Console.WriteLine("1"); }看看這兩個方法,其實第一個方法已經包括了第二個,但是編譯器並不會報錯。如果我們呼叫時,傳入 2 個整數,那麼會呼叫第二個方法列印 1 :
var a = new ExampleRef(); a.NormalMethod(1,2);C# 會先查詢沒有使用 params 的方法,如果找不到匹配的方法,才會去找帶有 paiams 的方法。
方法的重寫和隱藏涉及一對父子型別。如果父類別型有一個虛方法,那麼,子型別可以使用 override 顯式地重寫該方法,或者使用 new 隱藏該方法。提示:只有方法的最後一個引數才可以使用 params 關鍵字。
class Program { static void Main(string[] args) { A c1 = new C(); c1.Foo(); C c2 = new C(); c2.Foo(); Console.ReadKey(); } } class A { public virtual void Foo() { Console.WriteLine("Call on A.Foo()"); } } class B :A { public override void Foo() { Console.WriteLine("Call on B.Foo()"); } } class C :B { public new void Foo() { Console.WriteLine("Call on C.Foo()"); } }非常簡單直接,B 重寫了 A 的方法,而 C 隱藏了 B 的方法。
class Program { static void Main(string[] args) { //父類別的物件存取父類別的方法,去A的方法表 A a = new A(); a.NormalMethod(); a.NewMethod(); //子類的物件存取子類的方法,去B的方法表 B b = new B(); b.NormalMethod(); b.NewMethod(); //出現這種情況時,a2 的執行時型別為B,它會去B的方法表 //但它的編譯時物件為A A a2 = new B(); //B的方法表已經重寫了該方法,存取不到父類別的方法,只能存取子類的方法 a2.NormalMethod(); //B的方法表中有兩個NewMethod,根據編譯時的型別,呼叫父類別方法 a2.NewMethod(); Console.ReadKey(); } } class A { public virtual void NormalMethod() { Console.WriteLine("A.NormalMethod"); } public virtual void NewMethod() { Console.WriteLine("A.NewMethod"); } } class B :A { public override void NormalMethod() { Console.WriteLine("B.NormalMethod"); } public new void NewMethod() { Console.WriteLine("B.NewMethod"); } }輸出結果如下所示。
A.NormalMethod
A. NewMethod
B. NormalMethod
B.NewMethod
B.NormalMethod
A.NewMethod