简体   繁体   中英

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

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, eg 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();
        }
    }
}

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM