Как позвонить base.base.method ()? - PullRequest
       17

Как позвонить base.base.method ()?

102 голосов
/ 24 февраля 2010
// Cannot change source code
class Base
{
    public virtual void Say()
    {
        Console.WriteLine("Called from Base.");
    }
}

// Cannot change source code
class Derived : Base
{
    public override void Say()
    {
        Console.WriteLine("Called from Derived.");
        base.Say();
    }
}

class SpecialDerived : Derived
{
    public override void Say()
    {
        Console.WriteLine("Called from Special Derived.");
        base.Say();
    }
}

class Program
{
    static void Main(string[] args)
    {
        SpecialDerived sd = new SpecialDerived();
        sd.Say();
    }
}

Результат:

Вызывается из Специального Производного.
Вызывается из производного. / * этого не ожидается * /
Вызывается с базы.

Как мне переписать класс SpecialDerived, чтобы метод среднего класса "Derived" не вызывался?

UPDATE: Причина, по которой я хочу наследовать от Derived вместо Base, заключается в том, что класс Derived содержит множество других реализаций. Поскольку я не могу сделать base.base.method() здесь, я думаю, что лучший способ сделать следующее?

// Невозможно изменить исходный код

class Derived : Base
{
    public override void Say()
    {
        CustomSay();

        base.Say();
    }

    protected virtual void CustomSay()
    {
        Console.WriteLine("Called from Derived.");
    }
}

class SpecialDerived : Derived
{
    /*
    public override void Say()
    {
        Console.WriteLine("Called from Special Derived.");
        base.Say();
    }
    */

    protected override void CustomSay()
    {
        Console.WriteLine("Called from Special Derived.");
    }
}

Ответы [ 12 ]

0 голосов
/ 21 октября 2016

Если вы хотите получить доступ к данным базового класса, вы должны использовать ключевое слово "this" или использовать это ключевое слово в качестве ссылки для класса.

namespace thiskeyword
{
    class Program
    {
        static void Main(string[] args)
        {
            I i = new I();
            int res = i.m1();
            Console.WriteLine(res);
            Console.ReadLine();
        }
    }

    public class E
    {
        new public int x = 3;
    }

    public class F:E
    {
        new public int x = 5;
    }

    public class G:F
    {
        new public int x = 50;
    }

    public class H:G
    {
        new public int x = 20;
    }

    public class I:H
    {
        new public int x = 30;

        public int m1()
        {
           // (this as <classname >) will use for accessing data to base class

            int z = (this as I).x + base.x + (this as G).x + (this as F).x + (this as E).x; // base.x refer to H
            return z;
        }
    }
}
0 голосов
/ 21 мая 2016

Как видно из предыдущих постов, можно утверждать, что если необходимо обойти функциональность класса, то что-то не так в архитектуре класса. Это может быть правдой, но не всегда можно реструктурировать или реорганизовать структуру классов в большом зрелом проекте. Различные уровни управления изменениями могут быть одной из проблем, но сохранить работоспособность существующих функций после рефакторинга не всегда тривиальная задача, особенно если применяются временные ограничения. В зрелом проекте может оказаться довольно трудным препятствовать прохождению различных регрессионных тестов после реструктуризации кода; часто появляются неясные «странности». У нас была похожая проблема, в некоторых случаях унаследованная функциональность не должна выполняться (или должна выполнять что-то еще). Подход, который мы использовали ниже, заключался в том, чтобы поместить базовый код, который необходимо исключить, в отдельную виртуальную функцию. Затем эта функция может быть переопределена в производном классе, а функциональность исключена или изменена. В этом примере «Текст 2» можно запретить выводить в производный класс.

public class Base
{
    public virtual void Foo()
    {
        Console.WriteLine("Hello from Base");
    }
}

public class Derived : Base
{
    public override void Foo()
    {
        base.Foo();
        Console.WriteLine("Text 1");
        WriteText2Func();
        Console.WriteLine("Text 3");
    }

    protected virtual void WriteText2Func()
    {  
        Console.WriteLine("Text 2");  
    }
}

public class Special : Derived
{
    public override void WriteText2Func()
    {
        //WriteText2Func will write nothing when 
        //method Foo is called from class Special.
        //Also it can be modified to do something else.
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...