2012-07-12 75 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,因为它是直接匹配。

相关问题