我想在不继承基类的情况下覆盖类方法,因为它需要花费大量的时间和修改,因此需要进行越来越多的测试。就像这样:
class TestClass{
public void initialMethod(){
...
}
}
在代码的某处,我想做这样的事情:
public testMethod()
{
return;
}
test(){
changeMethod(TestClass.initialMethod, testMethod);
}
这个changeMethod函数会覆盖TestClass的initialMethod,所以它会调用testMethod。
使用常规做法继承和覆盖方法不是一种选择,因为这个类A是一个图形组件,并且它(并且更改它)会破坏大量代码。
编辑:我们没有TestClass的基本代码,因此不能修改定义initialMethod作为委托的代码。
编辑2:由于这是一个图形组件,设计人员自动添加了大量代码。如果我要继承此代码,我将不得不替换设计器添加的所有代码。这就是为什么我不想替换这个组件。
答案 0 :(得分:7)
您需要Strategy模式。
主要步骤:
如果工作不是那么大(让我们说只是颜色替换或其他什么)那么我同意Jhonny D. Cano用C#(匿名)代表的解决方案。
修改(编辑后2)
可能 - 就像概念验证一样 - 你应该继承该类并将所有从基类的引用替换为这个新类。这样做,没有别的。如果它有效,你可以考虑下一步(新方法或代表等)。
您只需要从版本控制系统中进行新的结帐,如果它可能失败,您可以放弃它。值得一试。
答案 1 :(得分:3)
也许你可以作为代表来做。
class TestClass {
public Action myAction;
public void initialMethod(){
...
}
initialMethod
public TestClass() {
myAction = initialMethod;
}
}
然后在TestMethod
上public testMethod()
{
return;
}
test() {
testClassInstance.myAction = testMethod;
}
答案 2 :(得分:2)
我认为你最好的选择是使用像LinFu这样的AOP框架。有一个代码项目文章解释它:
答案 3 :(得分:0)
如果'TestClass'是你定义的东西,你可以用属性和委托替换'initialMethod'定义,然后可以将其设置为具有给定签名的任何方法。 (即使是匿名的。)
class TestClass {
Action _myMethod;
Action MyMethod {
get { return _myMethod; }
set { _myMethod = value; }
}
var tc = new TestClass()
tc.MyMethod = () -> Console.WriteLine("Hello World!");
tc.MyMethod()
以上代码未经测试。
答案 4 :(得分:0)
如果您没有使用扩展方法的代码。
public void doSmth(this objectYOUWANT arg)
{
//Do Something
}
在这里,您使用Closed for Modification Open for Extension。
这将为您没有源代码的库添加功能。这样做非常干净。
版:
在FrameWork 3.5中,有一些新的扩展方法。这些方法为封闭的程序集添加了功能,使您可以在功能中扩展已关闭的dll /程序集。
要使用它,例如你有一个你导入的dll,称为Graphics.dll
(你的项目有参考)
首先,你要创建一个名为Extension
的新静态类:
public static class Extensions
{
}
其次,您希望为名为Graphics.dll
的{{1}}中包含的类添加额外的功能。你会这样做:
ChartGraph
第三,当你从public static class Extensions
{
public static void draw(this ChartGraph g)
{
// DO SOMETHING
}
}
实例化一个新对象时,你现在将拥有你创建的新方法:
graphics.dll
正如您所看到的那样,如果没有重新编译dll,您可以毫不费力地添加新功能,如果您没有源代码,那就很好。
答案 5 :(得分:0)
简短而简单的答案是:如果你不能调整基本的TestClass代码,不可以,你无法修改类来替换另一个方法。一旦我们开始做这样的事情,我们就会使用完全不同的语言,比如JavaScript。
答案越长:它取决于谁在调用替换方法。
如果是其他类,请查看是否无法在它们与不可修改的具体类之间实现Proxy。这是否可行取决于该类是实现接口,还是它自己的接口。
如果它是类本身,那么您唯一的选择是在设计时使用Reflector(或等效工具)或在运行时使用Reflection.Emit来反编译和修改类。然而,你必须非常伤害这条路线,因为它肯定是痛苦和脆弱的。
不幸的是,你仍然没有解释你正在尝试做什么以及为什么。在移动中替换方法是直接允许它的语言中的强大功能......可能有一些模拟库可以扭曲到足以完成反射的东西,但是你会在薄冰上滑冰。