I have a base class with some virtual functions
我有一个带有一些虚函数的基类
public class ABaseClass
{
public virtual void DoAThing()
{
print("print this base");
}
}
I have another class that inherits from the base class as below.
我有另一个继承自基类的类,如下所示。
public class AChildClass : ABaseClass
{
public override void DoAThing()
{
print("child override");
base.DoAThing();
}
}
During run-time I want to instantiate the child class while also wrapping/injecting/overriding a method it overrides in the base class to do as follows. I basically want to add to DoAThing method so that when it is called somewhere else it will do the extra code I added in.
在运行期间,我想实例化子类,同时包装/注入/覆盖它在基类中重写的方法,如下所示。我基本上想要添加到DoAThing方法,以便在其他地方调用它时,它将执行我添加的额外代码。
...
//somewhere else I instantiate and override the method at runtime
AChildClass instance = new AChildClass()
{
DoAThing = new method()
{
// Do some extra stuff
print("print this also");
// do child class stuff and base stuff
print("child override")
base.DoAThing(); //print("print this base");
}
}
Is this possible to do in C#?
这可能在C#中做到吗?
2 个解决方案
#1
2
You cannot overwrite a method once compiled in C#, unless you dynamically recompile.
除非动态重新编译,否则无法覆盖在C#中编译的方法。
As mentioned in the comments, one possible approach is to use a delegate. You can pass a delegate into an optional constructor and invoke it in DoAThing
if it has been passed in:
正如评论中所提到的,一种可能的方法是使用委托。您可以将委托传递给可选构造函数,并在DoAThing中调用它(如果已传入):
public class AChildClass : ABaseClass
{
private readonly Action _doAThing;
public AChildClass() { }
public AChildClass(Action doAThing)
{
_doAThing = doAThing;
}
public override void DoAThing()
{
if (_doAThing != null)
{
_doAThing();
}
print("child override");
base.DoAThing();
}
}
In your case, this would be instantiated as:
在您的情况下,这将被实例化为:
AChildClass instance = new AChildClass(() =>
{
// Do some extra stuff
print("print this also");
// do child class stuff and base stuff
print("child override")
});
which would fire two additional printed statements when invoked:
这将在调用时触发两个额外的打印语句:
instance.DoAThing();
print this also
打印这个也
child override
儿童覆盖
child override
儿童覆盖
print this base
打印这个基地
#2
2
An approach closest to what your pseudocode looks like would be adding an Action
delegate field to the base class like this:
最接近伪代码的方法是将Action委托字段添加到基类,如下所示:
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
AChildClass instance = new AChildClass()
{
DoSomethingExtra = () => Console.WriteLine("print this also")
};
instance.DoAThing();
}
}
public class ABaseClass
{
public Action DoSomethingExtra;
public virtual void DoAThing()
{
DoSomethingExtra();
Console.WriteLine("print this base");
}
}
public class AChildClass : ABaseClass
{
public override void DoAThing()
{
Console.WriteLine("child override");
base.DoAThing();
}
}
Output:
输出:
child override
print this also
print this base
Since it is a field, you could change the method the delegate points to anytime after instantiation:
由于它是一个字段,您可以在实例化后随时更改委托指向的方法:
instance.DoSomethingExtra = () => Console.WriteLine("new thing");
#1
2
You cannot overwrite a method once compiled in C#, unless you dynamically recompile.
除非动态重新编译,否则无法覆盖在C#中编译的方法。
As mentioned in the comments, one possible approach is to use a delegate. You can pass a delegate into an optional constructor and invoke it in DoAThing
if it has been passed in:
正如评论中所提到的,一种可能的方法是使用委托。您可以将委托传递给可选构造函数,并在DoAThing中调用它(如果已传入):
public class AChildClass : ABaseClass
{
private readonly Action _doAThing;
public AChildClass() { }
public AChildClass(Action doAThing)
{
_doAThing = doAThing;
}
public override void DoAThing()
{
if (_doAThing != null)
{
_doAThing();
}
print("child override");
base.DoAThing();
}
}
In your case, this would be instantiated as:
在您的情况下,这将被实例化为:
AChildClass instance = new AChildClass(() =>
{
// Do some extra stuff
print("print this also");
// do child class stuff and base stuff
print("child override")
});
which would fire two additional printed statements when invoked:
这将在调用时触发两个额外的打印语句:
instance.DoAThing();
print this also
打印这个也
child override
儿童覆盖
child override
儿童覆盖
print this base
打印这个基地
#2
2
An approach closest to what your pseudocode looks like would be adding an Action
delegate field to the base class like this:
最接近伪代码的方法是将Action委托字段添加到基类,如下所示:
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
AChildClass instance = new AChildClass()
{
DoSomethingExtra = () => Console.WriteLine("print this also")
};
instance.DoAThing();
}
}
public class ABaseClass
{
public Action DoSomethingExtra;
public virtual void DoAThing()
{
DoSomethingExtra();
Console.WriteLine("print this base");
}
}
public class AChildClass : ABaseClass
{
public override void DoAThing()
{
Console.WriteLine("child override");
base.DoAThing();
}
}
Output:
输出:
child override
print this also
print this base
Since it is a field, you could change the method the delegate points to anytime after instantiation:
由于它是一个字段,您可以在实例化后随时更改委托指向的方法:
instance.DoSomethingExtra = () => Console.WriteLine("new thing");