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#式解决方案?
拜托,帮帮我吧!
我前段时间在 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)
我想这与你想要做的有点相似。
不要查找委托本身,而是尝试查找该委托所需的类型。
| 归档时间: |
|
| 查看次数: |
623 次 |
| 最近记录: |