Reputation: 361
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.
...
//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#?
Upvotes: 1
Views: 776
Reputation: 13652
An approach closest to what your pseudocode looks like would be adding an Action
delegate field to the base class like this:
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");
Upvotes: 2
Reputation: 33833
You cannot overwrite a method once compiled in C#, unless you dynamically recompile.
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:
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
Upvotes: 2