C # разрешит ваш вызов к другой вашей реализации, потому что вызовы метода объекта, где класс для этого объекта имеет собственную реализацию, будут предпочтительнее переопределенной или унаследованной.
Это может привести к тонким и трудным для поиска проблемам, как вы показали здесь.
Например, попробуйте этот код (сначала прочитайте его, затем скомпилируйте и выполните), посмотрите, выполняет ли он то, что вы ожидаете.
using System;
namespace ConsoleApplication9
{
public class Base
{
public virtual void Test(String s)
{
Console.Out.WriteLine("Base.Test(String=" + s + ")");
}
}
public class Descendant : Base
{
public override void Test(String s)
{
Console.Out.WriteLine("Descendant.Test(String=" + s + ")");
}
public void Test(Object s)
{
Console.Out.WriteLine("Descendant.Test(Object=" + s + ")");
}
}
class Program
{
static void Main(string[] args)
{
Descendant d = new Descendant();
d.Test("Test");
Console.In.ReadLine();
}
}
}
Обратите внимание, что если вы объявите тип переменной типа Base
вместо Descendant
, вызов перейдет к другому методу, попробуйте изменить эту строку:
Descendant d = new Descendant();
к этому и повторите:
Base d = new Descendant();
Итак, как бы вы на самом деле смогли позвонить Descendant.Test(String)
тогда?
Моя первая попытка выглядит так:
public void Test(Object s)
{
Console.Out.WriteLine("Descendant.Test(Object=" + s + ")");
Test((String)s);
}
Это мне не помогло, и вместо этого просто вызывал Test(Object)
снова и снова для возможного переполнения стека.
Но работает следующее. Поскольку, когда мы объявляем переменную d
типа Base
, мы в конечном итоге вызываем правильный виртуальный метод, мы также можем прибегнуть к этой хитрости:
public void Test(Object s)
{
Console.Out.WriteLine("Descendant.Test(Object=" + s + ")");
Base b = this;
b.Test((String)s);
}
Это распечатает:
Descendant.Test(Object=Test)
Descendant.Test(String=Test)
Вы также можете сделать это снаружи:
Descendant d = new Descendant();
d.Test("Test");
Base b = d;
b.Test("Test");
Console.In.ReadLine();
распечатает то же самое.
Но сначала вы должны знать о проблеме , что совсем другое.