2012-07-12 77 views
0

我有幾個關於在C#中調用超載(或者我應該稱之爲隱藏)方法的問題。假設我的課程如下:C#如何搜索最佳匹配重載方法

class ParaA {} 
class ParaB : ParaA {} 
class ParaC : ParaB {} 

class TheBaseClass 
{ 
    public void DoJob (ParaA a){Console.WriteLine ("DoJob in TheBaseClass is being invoked");} 

} 

class TheDerivedClass : TheBaseClass 
{ 
    public void DoJob (ParaB b){Console.WriteLine ("DoJob in TheDerivedClass is being invoked");} 
} 

class Test 
{ 
    //Case 1: which version of DoJob() is being called? 
    TheDerivedClass aInstance= new TheDerivedClass(); 
    aInstance.DoJob(new ParaA()); 

    //Case 2: which version of DoJob() is being called? 
    TheBaseClass aInstance= new TheDerivedClass(); 
    aInstance.DoJob(new ParaA()); 

    //Case 3: which version of DoJob() is being called? 
    TheBaseClass aInstance= new TheDerivedClass(); 
    aInstance.DoJob(new ParaB()); 

    //Case 4: which version of DoJob() is being called? 
    TheBaseClass aInstance= new TheDerivedClass(); 
    aInstance.DoJob(new ParaC()); 

} 

我希望我已經明確了自己想要做的事情。我想知道當調用者提供的參數不完全匹配任何簽名但與某些簽名兼容時,C#將如何搜索調用的「匹配」版本的方法。當方法不僅在類中被重載,而且被派生類隱藏,覆蓋或重載時,它會讓我更加困惑。上面的示例並未涵蓋每種可能的情況。這有什麼期限嗎?

謝謝各位提前!

馬修

+0

您正在尋找「重載分辨率」,有關最佳細節,請參見[C#4.0語言規範](http://www.microsoft.com/en-us/download)中的第7.5.3節/details.aspx?id=7029)。至於你的哪些方法被調用,你可以通過你的程序來看看你自己。 [也見這些問題](http://stackoverflow.com/search?q=C%23+overload+resolution)。 – 2012-07-12 03:46:58

+0

謝謝安東尼。這正是我正在尋找的 – Xinchao 2012-07-12 07:16:58

回答

0

我已經添加了幾行,使代碼編譯:

void Main() 
{ 
    var t = new Test(); 
    t.Run(); 
} 
class ParaA {} 
class ParaB : ParaA {} 
class ParaC : ParaB {} 

class TheBaseClass 
{ 
    public void DoJob (ParaA a){Console.WriteLine ("DoJob in TheBaseClass is being invoked");} 

} 

class TheDerivedClass : TheBaseClass 
{ 
    public void DoJob (ParaB b){Console.WriteLine ("DoJob in TheDerivedClass is being invoked");} 
} 

public class Test 
{ 
    public void Run() 
    { 
     //Case 1: which version of DoJob() is being called? 
     TheDerivedClass aInstance= new TheDerivedClass(); 
     aInstance.DoJob(new ParaA()); 

     //Case 2: which version of DoJob() is being called? 
     TheBaseClass aInstance2= new TheDerivedClass(); 
     aInstance2.DoJob(new ParaA()); 

     //Case 3: which version of DoJob() is being called? 
     TheBaseClass aInstance3= new TheDerivedClass(); 
     aInstance3.DoJob(new ParaB()); 

     //Case 4: which version of DoJob() is being called? 
     TheBaseClass aInstance4= new TheDerivedClass(); 
     aInstance4.DoJob(new ParaC()); 
    } 
} 

的產生輸出:

DoJob in TheBaseClass is being invoked 
DoJob in TheBaseClass is being invoked 
DoJob in TheBaseClass is being invoked 
DoJob in TheBaseClass is being invoked 

即基類的方法被稱爲每次。

在情況1中,它被調用是因爲參數是ParaA,而ParaA不是ParaB。 在其他情況下,它被調用是因爲對象實例的類型是'TheBaseClass'。

這裏的改性來說明方法重載相同的代碼:

void Main() 
{ 
    var t = new Test(); 
    t.Run(); 
} 

class ParaA {} 
class ParaB : ParaA {} 
class ParaC : ParaB {} 

class TheBaseClass 
{ 
    public virtual void DoJob (ParaA a){Console.WriteLine ("DoJob in TheBaseClass is being invoked");} 

} 

class TheDerivedClass : TheBaseClass 
{ 
    public override void DoJob (ParaA b){Console.WriteLine ("DoJob in TheDerivedClass is being invoked");} 
} 

public class Test 
{ 
    public void Run() 
    { 
     //Case 1: which version of DoJob() is being called? 
     TheDerivedClass aInstance= new TheDerivedClass(); 
     aInstance.DoJob(new ParaA()); 

     //Case 2: which version of DoJob() is being called? 
     TheBaseClass aInstance2= new TheDerivedClass(); 
     aInstance2.DoJob(new ParaA()); 

     //Case 3: which version of DoJob() is being called? 
     TheBaseClass aInstance3= new TheDerivedClass(); 
     aInstance3.DoJob(new ParaB()); 

     //Case 4: which version of DoJob() is being called? 
     TheBaseClass aInstance4= new TheDerivedClass(); 
     aInstance4.DoJob(new ParaC()); 
    } 
} 

的輸出現在是:

DoJob in TheDerivedClass is being invoked 
DoJob in TheDerivedClass is being invoked 
DoJob in TheDerivedClass is being invoked 
DoJob in TheDerivedClass is being invoked 

TheDerivedClass方法被調用每次,因爲對象的類型爲「TheDerivedClass」。

0

Case2-4調用TheBaseClass只是因爲DoJob不是虛擬方法和aInstance類型是TheBaseClass

Case1調用TheBaseClass,因爲它是直接匹配。

相關問題