3

I have the following class

public class classB : classA 

which contains function dostuff

Now I have a class SUPER, which has an instance of B amongst its variables

classB SUPER_B;

and that has a 'redefinition' of 'dostuff' amongst its methods. Basically, what I need is that when classB calls 'dostuff', it does not call its internal dostuff, but SUPER's dostuff implementation instead.

Substantially, I would need that, on SUPER's initialization, classB's 'dostuff' be replaced with SUPER's dostuff.

It'd sort of make sense if there was a way to retrieve B's 'dostuff''s reference, but I don't know how to achieve that.

I've looked into virtual and Func, but they seem to require that SUPER be a derivate of B

NPE
  • 486,780
  • 108
  • 951
  • 1,012
roamcel
  • 645
  • 1
  • 8
  • 17
  • 4
    Please post the full code of the implementations of `dostuff` as defined on `classB` and `classA`, so we understand exactly what you are doing. – Oded Dec 10 '11 at 13:14
  • You've got some great suggestions here but that's as close as anyone can come without seeing some code or at least a statement of what your design motivation is. – Berryl Dec 10 '11 at 16:14
  • Thanks all for the extraordinary support and suggestions. Posting code is troublesome since the class names I'm using are abstractions of multi page real classes. What I am eventually trying to achieve is what @dasblinkenlight suggested: "replacing a function with another function", through the settable delegate, I didn't know the methodology nor definition, so I was unable to search for that differently. – roamcel Dec 11 '11 at 09:35

3 Answers3

3

You cannot force a method change upon a class from the outside. There are ways to achieve functionality like that when either (1) classB is designed in such a way as to support replacing its methods, e.g. though a settable delegate, or (2) if classB implements an interface, which you can implement, wrap classB inside it, and replace a method.

Example #1 - settable delegate:

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) {
    }
}

Example #2 - interfaces.

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();
        }
    }
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

It sounds like you need to use decorator pattern: class SUPER has an instance of classB and uses it's methods. SUPER decorates all necessary methods of classB, and adds some new. For example:

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
  }
}
a1ex07
  • 36,826
  • 12
  • 90
  • 103
  • In this case, why not just inherit classB? – Dexter Dec 10 '11 at 13:24
  • 1
    @Dexter: OP says an instance of `classB` is a member of `SUPER`. I suppose that inheritance is not an option in his case. Otherwise, there is no question, since derived class can always overwrite non-sealed method. – a1ex07 Dec 10 '11 at 13:27
  • @Dexter: cause you in this case enable access to ALL public/protected members of classB, which may be OP doesm't want. Cause this could be substantial change in your program architecture. Cause, may be, you can not as class is sealed.... – Tigran Dec 10 '11 at 13:30
  • This is actually one very good solution, too. Regarding prerequisites, a1ex07's intuitions are correct. – roamcel Dec 11 '11 at 10:20
0

You can't do that easily.

Instead you should design your classB for extensibility, such as add events to classB which you can handle in your SUPER class.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825