gpt4 book ai didi

c# - 可以在此通用代码中避免使用 Delegate.DynamicInvoke 吗?

转载 作者:可可西里 更新时间:2023-11-01 08:33:07 27 4
gpt4 key购买 nike

这个问题部分是关于委托(delegate)的,部分是关于泛型的。

给定简化代码:

internal sealed class TypeDispatchProcessor
{
private readonly Dictionary<Type, Delegate> _actionByType
= new Dictionary<Type, Delegate>();

public void RegisterProcedure<T>(Action<T> action)
{
_actionByType[typeof(T)] = action;
}

public void ProcessItem(object item)
{
Delegate action;
if (_actionByType.TryGetValue(item.GetType(), out action))
{
// Can this call to DynamicInvoke be avoided?
action.DynamicInvoke(item);
}
}
}

我读了elsewhere on SO直接调用委托(delegate)(带括号)比调用 DynamicInvoke 快几个数量级,这是有道理的。

对于上面的代码示例,我想知道我是否可以执行类型检查并以某种方式提高性能。

一些上下文:我有一个对象流,这些对象被分配给各种处理程序,并且可以在运行时注册/取消注册这些处理程序。上面的模式非常适合我的目的,但如果可能的话,我想让它更快捷。

一种选择是存储 Action<object>Dictionary , 并包装 Action<T>委托(delegate)与另一个委托(delegate)。我还没有比较第二次间接调用会影响的性能变化。

最佳答案

我强烈怀疑包装调用会比使用 DynamicInvoke 更有效。您的代码将是:

internal sealed class TypeDispatchProcessor
{
private readonly Dictionary<Type, Action<object>> _actionByType
= new Dictionary<Type, Action<object>>();

public void RegisterProcedure<T>(Action<T> action)
{
_actionByType[typeof(T)] = item => action((T) item);
}

public void ProcessItem(object item)
{
Action<object> action;
if (_actionByType.TryGetValue(item.GetType(), out action))
{
action(item);
}
}
}

值得对其进行基准测试,但我认为您会发现它效率更高。 DynamicInvoke 必须使用反射等检查所有参数,而不是包装委托(delegate)中的简单转换。

关于c# - 可以在此通用代码中避免使用 Delegate.DynamicInvoke 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1116073/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com