在 C# 中使用反射重写虚拟方法表
有没有办法更改 C# 中的虚拟方法表?比如改变虚拟方法指向的位置?
class A
{
public virtual void B()
{
Console.WriteLine("B");
}
}
class Program
{
public static void MyB(A a)
{
Console.WriteLine("MyB");
}
public static void Main(string[] Args)
{
A a = new A();
// Do some reflection voodoo to change the virtual methods table here to make B point to MyB
a.B(); // Will print MyB
}
}
Is there a way to change the virtual methods tables in C#? like change where a virtual method is pointing?
class A
{
public virtual void B()
{
Console.WriteLine("B");
}
}
class Program
{
public static void MyB(A a)
{
Console.WriteLine("MyB");
}
public static void Main(string[] Args)
{
A a = new A();
// Do some reflection voodoo to change the virtual methods table here to make B point to MyB
a.B(); // Will print MyB
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看看 LinFu。
在 Linfu 作者的博客上有一个使用 LinFu 的示例。 AOP 可以拦截和更改对您不直接控制的类的方法的调用。
Take a look at LinFu.
On Linfu's author's Blog there's an example of using LinFu.AOP to intercept and change calls even to methods of classes that you don't control directly.
您无法通过反射更改类型,只能反射现有类型。
但是,您可以使用 Reflection.Emit 和相关类构建新类型,但无需重新编译程序集,示例中的
aB();
将始终调用AB()
。You cannot change the types with reflection, you can only reflect over the existing types.
You can, however, build new types using Reflection.Emit and related classes, but short of recompiling your assembly,
a.B();
in your example will always callA.B()
.丹尼,
你的实际问题是什么?给我描绘一幅“动态”“打破”现有的、经过测试的类定义的图片。请原谅我的怀疑……但我有丰富的脚本编写经验,因此我将采用在任何一天运行时都不会自行生成的代码。正是因为这个原因,我什至(有点)讨厌国际奥委会。
但是,如果您想“即时”创建一个覆盖(或实现)类定义,那么我想您会使用字节码生成(至少这就是您在 Java 中所做的)...这是一个论坛关于该主题的线程:http://bellyphant.com/2006/11/csharp_bytecode_ Generation
您还可以生成源代码,并即时编译它。这是一个可爱的免费小工具类,用于动态编译 C#: http://www.agilekiwi.com/on_the_fly .htm
无论如何,祝你好运......这是一个有趣的问题。
干杯。基思.
Dani,
What's your ACTUAL problem? Paint me a picture of where-abouts "breaking" an existing, tested class definition "on the fly" would be desirable. Forgive my scepticism... but I have plenty of scripting experience, so I'll take code that doesn't generate itself as it's running any day. I even (sort of) hate IOC for just that reason.
However, If you want to create an overriding (or implementing) class-definitions "on the fly" then I suppose you'd use byte-code-generation (atleast that's what you'd do in Java)... Here's a forum thread on that topic: http://bellyphant.com/2006/11/csharp_bytecode_generation
You could also generate source-code, and compiling it on the fly. Here's a cute free little utils class to compile C# on the fly: http://www.agilekiwi.com/on_the_fly.htm
Good luck with it anyway... It's an interesting question.
Cheers. Keith.
您可以将虚拟 B 呼叫设置为您选择的默认委托。
以下将允许继承和覆盖:(实际上覆盖已经覆盖的:D)
输出:
您甚至可以在 cB.B() 中调用
base.B();
,这将有效地调用覆盖的委托,但将给出以下输出:我建议您采取一些类似的方法或设计模式方法,甚至不要考虑反射 Emit。您的代码将无法在高性能应用程序中使用。代表很快,反思很慢。
You can make virtual B call a default delegate you choose.
The following will allow inheritance and overriding: (actually overriding of already overriden :D)
Output:
You can even call
base.B();
in cB.B() which will effectively call the overriden delegate but will give this output:I suggest you to take some similar approach or a design pattern approach and do not even think of reflection Emit. You code will be unusable in high performance applications. Delegates are fast, reflection is SLOW.