在运行时实例化时动态包装C#方法的内容

时间:2018-05-01 17:57:28

标签: c# .net override wrapper code-injection

我有一个带有一些虚函数的基类

public class ABaseClass
{
    public virtual void DoAThing()
    {
        print("print this base");
    } 
}

我有另一个继承自基类的类,如下所示。

public class AChildClass : ABaseClass
{
    public override void DoAThing()
    {
        print("child override");
        base.DoAThing();
    } 
}

在运行期间,我想实例化子类,同时包装/注入/覆盖它在基类中重写的方法,如下所示。我基本上想要添加到 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");
    }
}

这可以用C#做​​吗?

2 个答案:

答案 0 :(得分:2)

除非动态重新编译,否则无法覆盖在C#中编译的方法。

正如评论中所提到的,一种可能的方法是使用委托。您可以将委托传递给可选构造函数,并在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();
    }
}

在您的情况下,这将被实例化为:

AChildClass instance = new AChildClass(() => 
{
    // Do some extra stuff
    print("print this also");

    // do child class stuff and base stuff
    print("child override")
});

在调用时会触发另外两个打印的语句:

instance.DoAThing();
  

也打印

     

子覆盖

     

子覆盖

     

打印此基地

答案 1 :(得分:2)

最接近伪代码的方法是将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();
    }
}

输出:

child override
print this also
print this base

由于它是一个字段,您可以在实例化后随时更改委托指向的方法:

instance.DoSomethingExtra = () => Console.WriteLine("new thing");