C# 如何调用具有重载的重写方法?

C# 如何调用具有重载的重写方法?,c#,overriding,overloading,C#,Overriding,Overloading,我有以下简单的代码 abstract class A { public abstract void Test(Int32 value); } class B : A { public override void Test(Int32 value) { Console.WriteLine("Int32"); } public void Test(Double value) { Test((Int32)1);

我有以下简单的代码

abstract class A
{
    public abstract void Test(Int32 value);
}

class B : A
{
    public override void Test(Int32 value)
    {
        Console.WriteLine("Int32");
    }

    public void Test(Double value)
    {
        Test((Int32)1);
    }
}
当我运行这段代码时,行测试((Int32)1)由于无限递归而导致堆栈溢出。正确调用我找到的正确方法(使用整型参数)的唯一可能方法是

(this as A).Test(1);

但这不适合我,因为这两种方法测试都是公共的,我希望用户能够调用这两种方法?

不幸的是,为了通过
B
引用调用
A::Test(int)
,需要某种类型的强制转换。只要C#编译器通过
B
查看引用,它就会选择
B::Test(double)
版本

下面是一个稍微不那么难看的版本

((A)this).Test(1);
不过,另一个想法是,使用一个名称不同的私有方法,这两个方法都可以输入到

class B : A { 
  public override void Test(int i) {
    TestCore(i);
  }
  public void Test(double d) {
    TestCore(1);
  }
  private void TestCore(int i) {
    // Combined logic here
  }
}

C#中的方法重载解析并不总是像您预期的那样,但是您的代码是按照规范运行的(我不久前就写过这个)

简而言之,编译器从查找

  • 具有相同的名称(在您的案例中为
    Test
  • 在类型(在本例中为
    B
    )或其一个基类型中声明
  • 未使用覆盖修饰符声明
请注意最后一点。这实际上是合乎逻辑的,因为虚拟方法是在运行时解析的,而不是在编译时解析的

最后,如果类型(在本例中为
B
)有一个候选方法(这意味着调用中的参数可以隐式转换为候选方法的参数类型),则将使用该方法。您的重写方法甚至不是决策过程的一部分

如果要调用重写的方法,首先需要将对象强制转换为其基类型