Функция переопределения в не производном классе c # - PullRequest
3 голосов
/ 10 декабря 2011

У меня есть следующий класс

public class classB : classA 

, который содержит функцию dostuff

Теперь у меня есть класс SUPER, который имеет экземпляр B среди своих переменных

classB SUPER_B;

, и среди его методов есть переопределение «dostuff».По сути, мне нужно, чтобы когда classB вызывал 'dostuff', он не вызывал свой внутренний dostuff, а вместо этого реализовывал SUPER dostuff.

По существу, мне нужно, чтобы при инициализации SUPER 'dostuff' класса B былзаменен на SUPER's dostuff.

Было бы разумно, если бы был способ получить ссылку B на 'dostuff', но я не знаю, как этого добиться.

Я посмотрел на virtual и Func, но они, кажется, требуют, чтобы SUPER был производным от B

Ответы [ 3 ]

3 голосов
/ 10 декабря 2011

Вы не можете принудительно изменить метод для класса извне. Существуют способы достижения такой функциональности, когда (1) classB разработан таким образом, чтобы поддерживать замену его методов, например через настраиваемый делегат, или (2) если classB реализует интерфейс, который вы можете реализовать, оберните внутри него classB и замените метод.

Пример # 1 - настраиваемый делегат:

class ClassB {
    public Action<int> dostuff {get;set;}
    public ClassB() {
        dostuff = myDoStuff;
    }
    void myDoStuff(int n) {
    }
}

class Program {
    public static void Main() {
        var myB = new ClassB();
        myB.dostuff = myOverride;
    }
    void myOverride(int n) {
    }
}

Пример # 2 - интерфейсы.

interface IClassB {
    void dostuff(int n);
    void dosomething();
}
class ClassB : IClassB {
    void dostuff(int n) {
    }
    void dosomething() {
    }
}
class Program {
    public static void Main() {
        var bb = new Override(new ClassB());
    }
    class Override : IClassB {
        private readonly IClassB inner;
        public Override(IClassB inner) {
            this.inner = inner;
        }
        void dostuff(int n) {
            // do not call inner.dostuff
        }
        void dosomething() {
            inner.dosomething();
        }
    }
}
2 голосов
/ 10 декабря 2011

Похоже, вам нужно использовать шаблон декоратора: класс SUPER имеет экземпляр classB и использует его методы. SUPER украшает все необходимые методы classB и добавляет некоторые новые. Например:

public class SUPER {
  private classB SUPER_B = new classB();
  public void foo()  {
     SUPER_B.foo();
  }
  public void bar()  {
     SUPER_B.bar();
  }
  ...
  public void dostuff()
  {
       // don't call SUPER_B.bar(), but write your implementation
  }
}
0 голосов
/ 10 декабря 2011

Вы не можете сделать это легко.

Вместо этого вы должны разработать свой classB для расширяемости, например добавить события в classB, которые вы можете обрабатывать в своем классе SUPER.

...