Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在运行时实例化时动态包装C方法的内容_C#_.net_Overriding_Wrapper_Code Injection - Fatal编程技术网

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

C# 在运行时实例化时动态包装C方法的内容,c#,.net,overriding,wrapper,code-injection,C#,.net,Overriding,Wrapper,Code Injection,我有一个基类和一些虚拟函数 public class ABaseClass { public virtual void DoAThing() { print("print this base"); } } 我有另一个从基类继承的类,如下所示 public class AChildClass : ABaseClass { public override void DoAThing() { print("child over

我有一个基类和一些虚拟函数

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语言中可以这样做吗

除非动态地重新编译,否则在用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();
也打印这个

子覆盖

子覆盖

打印此底座


除非动态地重新编译,否则在用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();
也打印这个

子覆盖

子覆盖

打印此底座


最接近伪代码外观的方法是向基类添加操作委托字段,如下所示:

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");

最接近伪代码外观的方法是向基类添加操作委托字段,如下所示:

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");

您应该对接受委托的DoAThing进行重载。您可以将委托传递给将在实现中使用的构造函数。然而,这似乎是一件奇怪的事情。您要解决的问题是什么?您应该为接受委托的DoAThing设置重载。您可以将委托传递给将在实现中使用的构造函数。然而,这似乎是一件奇怪的事情。您要解决的问题是什么?输出不是先是子覆盖,然后再打印此内容并打印此基础吗?@BlakeThingstad是的,这是一个错误:输出不是先是子覆盖,然后再打印此内容并打印此基础吗?@BlakeThingstad是的,这是一个错误: