没有代表的钩子功能(反射)

时间:2018-01-16 18:13:34

标签: c# unity3d reflection

有没有办法可以使用反射将一个函数挂钩到另一个函数而不使用委托?

class A
{
    void Foo()
    {
    }
}

class B
{
    void Main()
    {
        A a = new A();
        a.GetType().GetMethod("Foo").AddHook(a, Func); //I want something like this
        a.Foo();
        //Func gets called
    }

    void Func()
    {
    }
}

有没有办法在调用Func后调用Foo而不使用事件,委托或只是从Func内部调用Foo

我需要这个,所以我的游戏UI控制器可以更新。

我看到大多数人处理这个问题的方法是向A添加一堆事件并为这些事件订阅B.喜欢这个

class A
{
‎    public delegate void UICallback();
‎    public event UICallback onFoo;
    void Foo()
    {
    ‎    onFoo.Invoke();
    }
}

class B
{
    void Main()
    {
        A a = new A();
        ‎a.onFoo += Func;
        a.Foo();
    }

    void Func()
    {
    }
}

我用这种方法发现的问题是我需要在很多类中添加一些这样的事件(可能超过5甚至10),然后记得在函数结束时调用它们更新UI(例如,在StartBattle()结束时调用onBattleStarted)。除了使用大块事件声明增加我的类的大小使其难以阅读之外,这使得它更难维护。

编辑我认为没有人真正理解我正在寻找的东西...我想要一种方法将Func挂钩到FooFoo进行任何更改,即没有Foo知道此回调存在。使用操作无济于事,因为我需要在Foo的参数上指定它应该调用Func

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

你可以在Func()的末尾调用Action。

Class A
{
   void Foo()
   {
   }
}

Class B
{
   void Main()
   {
    A a = new A();
    Func( () => {a.Foo();});
   }

   void Func(Action onFinish)
   {
    //Enter your code here
    onFinish();
   }

答案 1 :(得分:0)

如果可以解决您的问题,则有方法链接模式:

namespace Assets
{
    public class Example
    {
        public Example GrabSomeFoodInTheFridge()
        {
            // some work
            return this;
        }

        public Example WatchTv()
        {
            // some work
            return this;
        }

        public Example EatFood()
        {
            // some work
            return this;
        }
    }

    public class Demo
    {
        public Demo()
        {
            var example = new Example();

            var instance = example
                .GrabSomeFoodInTheFridge()
                .EatFood()
                .WatchTv();
        }
    }
}

它根本不使用反射,另外你可以利用接口和扩展方法。