Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override function in non derived c# class

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

like image 866
roamcel Avatar asked Feb 18 '26 15:02

roamcel


2 Answers

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();
        }
    }
}
like image 172
Sergey Kalinichenko Avatar answered Feb 20 '26 03:02

Sergey Kalinichenko


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
  }
}
like image 35
a1ex07 Avatar answered Feb 20 '26 04:02

a1ex07



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!