Using reflection to override virtual method tables in C#

别等时光非礼了梦想. 提交于 2019-12-05 14:25:19

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.

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 call A.B().

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.

You can make virtual B call a default delegate you choose. The following will allow inheritance and overriding: (actually overriding of already overriden :D)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class A
{
    public delegate void delegateB();
    public delegateB _B;

    public A() {
      _B = B;
    }
    public void Override(delegateB newB)
    {
        _B = newB;
    }

    public virtual void B()
    {
        if (_B != null && _B != this.B) {
            Console.WriteLine("OVERRIDEN B IN A");
            _B();
        }
        else {
        Console.WriteLine("VIRTUAL B IN A");
        }
    }
}

    class cB : A {
        public override void B() {
            if (base._B != null && base._B != this.B)
            {
                Console.WriteLine("OVERRIDEN B IN B");
                _B();
            }
            else
            {
                Console.WriteLine("IN B");
            }

        }
    }

class Program
{
    class Overrider {
       public void MyB()
       {
           Console.WriteLine("MyB");
       }
    }

    public static void Main(string[] Args)
    {
        A a = new A();
        a.B();
        Overrider ovr = new Overrider();
        a.Override(ovr.MyB);
        a.B(); // Will print MyB
        cB b = new cB();
        b.B();
        b.Override(ovr.MyB);
        b.B();
    }
}
}

Output:

VIRTUAL B IN A
OVERRIDEN B IN A
MyB
IN B
OVERRIDEN B IN B
MyB

You can even call base.B(); in cB.B() which will effectively call the overriden delegate but will give this output:

VIRTUAL B IN A
OVERRIDEN B IN A
MyB
IN B
OVERRIDEN B IN B
OVERRIDEN B IN A
MyB

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!