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();
распечатает то же самое.
Но сначала вам нужно знать о проблеме, а это совсем другое.
person
Lasse V. Karlsen
schedule
02.12.2009
MySubClass
? - person Bruno Reis   schedule 02.12.2009