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#将如何搜索要调用的方法的"匹配"版本。当方法不仅在类中重载,而且被派生类隐藏、重写或重载时,这让我更加困惑。上面的例子并没有涵盖所有可能的情况。这有什么术语吗?

提前谢谢大家!

Matthew

我添加了几行代码来编译:

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

每次都调用DerivedClass方法,因为对象的类型为"TheDerivedCClass"。

Case2-4调用TheBaseClass只是因为DoJob不是虚拟方法,并且aInstance的类型是TheBaseClass

Case1调用TheBaseClass,因为它是一个直接匹配。

相关内容

  • 没有找到相关文章

最新更新