在非派生 C# 类中覆盖函数

3
我有下面这个类:

public class classB : classA 

其中包含函数dostuff

现在我有一个类SUPER,它的变量中有一个B的实例

classB SUPER_B;

它的方法之一是'redefinition'的'dostuff'。 基本上,当classB调用'dostuff'时,我需要的是它不调用其内部的dostuff,而是调用SUPER的dostuff实现。

实质上,在SUPER的初始化中,我需要将classB的'dostuff'替换为SUPER的dostuff。

如果有一种方式可以检索B的'dostuff'的引用,那么这似乎是有道理的,但我不知道如何实现。

我已经研究了虚拟和Func,但它们似乎要求SUPER是B的衍生物。


4
请发布classBclassAdostuff实现的完整代码,以便我们确切了解您正在做什么。 - Oded
你在这里提出了一些很好的建议,但是如果没有看到一些代码或者至少知道你的设计动机,那么这就是最接近的了。 - Berryl
感谢大家的非凡支持和建议。由于我使用的类名是多页真实类的抽象,所以发布代码很麻烦。最终我想要实现的是@dasblinkenlight建议的“用另一个函数替换函数”,通过可设置的委托,我不知道方法论或定义,所以无法以其他方式搜索。 - roamcel
3个回答

3
您不能从外部强制更改一个类的方法。有两种方式可以实现类似的功能,一是让classB在设计时支持替换其方法,例如通过可设置的委托;二是如果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

听起来你需要使用装饰器模式:类 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
  }
}

在这种情况下,为什么不直接继承classB呢? - Dexter
1
@Dexter:OP 说 classB 的一个实例是 SUPER 的成员。我猜在他的情况下继承不是一个选项。否则,问题就不存在了,因为派生类总可以覆盖非密封方法。 - a1ex07
@Dexter:因为在这种情况下,你启用了对classB的所有公共/受保护成员的访问,而这可能不是OP想要的。因为这可能是程序架构上的重大变化。因为也许你不能像class一样密封它。 - Tigran
这实际上是一个非常好的解决方案。关于先决条件,a1ex07的直觉是正确的。 - roamcel

0

你不能轻易地这样做。

相反,你应该为可扩展性设计你的classB,例如在classB中添加事件,你可以在你的SUPER类中处理它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接