在运行时替换.NET类型

时间:2009-12-07 20:10:32

标签: .net

我有一个.NET程序集,它在编译时定义了一个类型T,并且我已经将对象my_t实例化为此类型的实例。

我想知道在.NET中是否可以使用运行时编译器服务来重新编译这个类,然后将新的类定义加载到当前正在执行的程序集中,所以当我从my_t调用方法时,他们将使用新代码。

我没有改变任何方法的签名,只改变方法体。

任何.NET大师都知道这是否可行?在此先感谢您的帮助!

5 个答案:

答案 0 :(得分:7)

可以交换方法实现,但如果运行不安全代码是一个选项,并且您想要交换的方法未被NGen或“Zapped”

基本过程在概念上非常简单:你将方法的JIT代码所在的内存地址与另一个方法的JIT代码的内存地址交换(你也可以强制CLR在你的方法中JIT你的方法)第一名,以避免一个奇怪的先决条件问题。)

CodeProject.com上有一个很棒的概念验证项目: http://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer

去看看吧!

答案 1 :(得分:3)

我不确定这是否可能,但如果是的话,这听起来像是一个非常混乱的解决方案。

使用插件架构,因此您可以动态编译生成的插件,继承自插件界面,只需从新创建的程序集中加载该类型,然后将其插入到插件容器中。

答案 2 :(得分:2)

您可以使用城堡动态代理来创建班级的代理。代理是一种新类型,可以让您注入新的实现,但是您要注入的任何内容都必须声明为虚拟。

答案 3 :(得分:1)

.NET对象无法在运行时更改类型;这是CLR的一个基本假设。

一些建议:

  1. 编写T的代码,以根据需要将呼叫转发到正确的类型。如果你愿意,它可以转发到在运行时编译的类型。
  2. 使用某种面向方面或动态代理框架为您自动化(1)
  3. 如果这种转发不合适,我相信本机可以使用.NET分析API来拦截JIT进程。我所知道的就是像NCover这样的工具能够以这种方式注入自己的机器代码。

答案 4 :(得分:0)

扩展我的评论:

public class Base
{
    public virtual void Method()
    {

    }
}

public class Sub : Base
{
    public override void Method()
    {

    }
}

public void DoStuff<T>() where T : Base, new()
{
    var instance = new T();
    instance.Method();
}