1

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#?

Shabloinker
  • 361
  • 2
  • 9
  • 1
    You should make an overload of `DoAThing()` that accepts a delegate – maccettura May 01 '18 at 18:00
  • 1
    You could pass a delegate to the constructor that would be used in your implementation. However this seems like an odd thing to want to do. What problem are you working on that you need to do this for? – juharr May 01 '18 at 18:02

2 Answers2

2

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

David L
  • 32,885
  • 8
  • 62
  • 93
2

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");
adjan
  • 13,371
  • 2
  • 31
  • 48