关于c#delegate创建的性能

Nee*_*eed 6 c# reflection delegates

我的项目涉及很多反思.所以,我在字典中缓存了代表.问题是我选择使用MethodInfo作为dict键,我试图使用查找方法,这是这样的:

Func<T,R> LookUp(Func<T,R> m)
{
  return (Func<T,R>)dict[m.Method];
}
//LookUp(MyCls.Method)
Run Code Online (Sandbox Code Playgroud)

但是,在做了一些测试之后,我发现用一个函数地址来提供LookUp方法,即动态创建过渡代表,有点慢,非常慢:

class MyCls
{
    public static void Operate(int whatever){ }
}

class MainClass
{
    delegate void Doer<T>(T arg);
    static Dictionary<MethodInfo,Delegate> _dict = new Dictionary<MethodInfo,Delegate>();

public static void Main (string[] args)
    {
        Action<int> dg = MyCls.Operate;
        _dict[dg.Method] = Delegate.CreateDelegate(typeof(Action<int>),dg.Method);

        //performance test
        var start = Environment.TickCount;          
        for (int i = 0; i < 10000000; i++)
        {
            //LookUp(dg);//11               
            //LookUp<int>(MyCls.Operate);//1503
            //new MyCls();//431
        }

        Console.WriteLine (Environment.TickCount-start);
    }
    static  Action<T> LookUp<T>(Action<T> dg) 
    {
        //should return (Action<T>)_dict[dg.Method];
        return null;
    }
Run Code Online (Sandbox Code Playgroud)

因此,问题是:为了提高性能,我应该改变我的方法,编写一些不安全的代码(函数指针甚至是c#支持的吗?)还是有针对这种情况的替代c#式解决方案?

拜托,帮帮我吧!

Rag*_*ghu 1

我前段时间在 Winform 应用程序中使用了一个类进行事件聚合(Mediator),该应用程序具有 Type 作为键和 Delegate 作为值的字典缓存。班级看起来像...

public sealed class EventAggregator
    {
        #region Fields

        private readonly Dictionary<Type, List<Object>> subscribers = new Dictionary<Type, List<Object>>();

        #endregion

        #region Public Methods

        public void Subscribe<TMessage>(Action<TMessage> handler)
        {
            if (subscribers.ContainsKey(typeof(TMessage)))
            {
                var handlers = subscribers[typeof(TMessage)];
                handlers.Add(handler);
            }
            else
            {
                var handlers = new List<Object> {handler};
                subscribers[typeof(TMessage)] = handlers;
            }
        }

        public void Unsubscribe<TMessage>(Action<TMessage> handler)
        {
            if (subscribers.ContainsKey(typeof(TMessage)))
            {
                var handlers = subscribers[typeof(TMessage)];
                handlers.Remove(handler);

                if (handlers.Count == 0)
                {
                    subscribers.Remove(typeof(TMessage));
                }
            }
        }

        public void Publish<TMessage>(TMessage message)
        {
            if (subscribers.ContainsKey(typeof(TMessage)))
            {
                var handlers = subscribers[typeof(TMessage)];
                foreach (Action<TMessage> handler in handlers)
                {
                    handler.Invoke(message);
                }
            }
        }

        #endregion
    }
Run Code Online (Sandbox Code Playgroud)

我想这与你想要做的有点相似。

不要查找委托本身,而是尝试查找该委托所需的类型。