Вызов метода дочернего класса из родительского

Возможно ли, чтобы метод a.doStuff() напечатал "B did stuff" без редактирования класса A? Если да, то как мне это сделать?

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B();

        a.doStuff();
        b.doStuff();

        Console.ReadLine();
    }
}

class A
{
    public void doStuff()
    {
        Console.WriteLine("A did stuff");
    }
}

class B : A
{
    public void doStuff()
    {
        Console.WriteLine("B did stuff");
    }
}

Я играю в парную игру, Террария. И я не хочу декомпилировать и перекомпилировать все это, потому что это будет завинчиваться с паром. Моя программа "вводит" в Terraria через XNA. Я могу использовать методы update() и draw() из XNA, чтобы модифицировать некоторые вещи. Но это довольно ограничено. Я не буду переопределять базовые методы, чтобы модифицировать больше вещей (например, worldgen).

Ответ 1

Да, если вы объявите doStuff как virtual в A, а затем override в B.

class A
{
    public virtual void doStuff()
    {
        Console.WriteLine("A did stuff");
    }
}

class B : A
{
    public override void doStuff()
    {
        Console.WriteLine("B did stuff");
    }
}

Ответ 2

Так как B эффективно A-наследование и метод перегружен.

A a = new B();
a.doStuff();

Ответ 3

Код для классов A и B, которые вы опубликовали, будет генерироваться ниже предупреждения компилятора и попросит использовать ключевое слово new для класса B, хотя оно будет скомпилировано: Ключевое слово new требуется для "B.doStuff()", поскольку оно скрывает унаследованный элемент "A.doStuff()"

Используйте method hiding вместе с ключевыми словами new и virtual в классе Mapper и классе B следующим образом:

class Program
{
    static void Main(string[] args)
    {
        Mapper a = new B(); //notice this line
        B b = new B();

        a.doStuff();
        b.doStuff();

        Console.ReadLine();
    }
}

class A
{
    public void doStuff()
    {
        Console.WriteLine("A did stuff");
    }
}

class Mapper : A
{
    new public virtual void doStuff() //notice the new and virtual keywords here which will all to hide or override the base class implementation
    {
        Console.WriteLine("Mapper did stuff");
    }
}

class B : Mapper
{
    public override void doStuff()
    {
        Console.WriteLine("B did stuff");
    }
}