0

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

提前谢谢你们!

马修

4

2 回答 2

0

Case2-4 调用TheBaseClass仅仅是因为 DoJob 不是虚拟方法并且类型aInstanceTheBaseClass.

Case1 调用TheBaseClass是因为它是直接匹配的。

于 2012-07-12T03:52:02.137 回答
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

每次都会调用 DerivedClass 方法,因为对象是“TheDerivedClass”类型。

于 2012-07-12T03:58:20.613 回答