为何无法将方法委托传入ConcurrentDictionary的GetOrAdd()方法?
问题解决方法
错误原因分析
编译错误CS1593的根源是:
ConcurrentDictionary.GetOrAdd的第二个参数要求是Func<Type, MethodInfo>类型的委托,即必须接收一个Type类型的输入参数,但你定义的getMethodInfo是无参方法,且调用时写成()=>getMethodInfo,既没有传递必要的Type参数,也没有正确调用方法(这里是返回方法本身而非方法执行结果)。
修正步骤
1. 调整getMethodInfo方法,添加Type参数
将硬编码的typeof(TITarget)替换为传入的Type参数,让方法能针对不同的类型查找对应的Update方法:
private static MethodInfo getMethodInfo(Type targetType) { var types = getInheritanceHierarchy(targetType); var findUpdateMethod = targetType .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.Name == "Update"); var methodInfo = types.Join( findUpdateMethod, t => t.Name, mi => mi.DeclaringType.Name, (t, mi) => mi) .FirstOrDefault(); // 用FirstOrDefault避免找不到方法时抛出异常 if (methodInfo == null) { throw new InvalidOperationException($"未在类型{targetType.Name}及其继承链中找到公共实例方法Update"); } return methodInfo; }
2. 修正GetOrAdd的委托调用
在GetOrAdd中传递Type参数,并正确调用getMethodInfo方法:
public void Update(TITarget target) { var targetType = typeof(TITarget); // 直接传递方法引用即可,签名与GetOrAdd要求的委托匹配 var methodInfo = dic.GetOrAdd(targetType, getMethodInfo); methodInfo.Invoke(target, new object[] { this }); }
3. 可选优化:确保方法参数匹配
额外检查找到的Update方法是否符合参数要求(接收当前类实例作为参数),避免调用时出错:
在getMethodInfo的筛选条件中添加参数校验:
var findUpdateMethod = targetType .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.Name == "Update" && x.GetParameters().Length == 1 && x.GetParameters()[0].ParameterType == typeof(你的当前类名称)); // 替换成实际的当前类名
内容的提问来源于stack exchange,提问作者shirin monzavi
相关产品推荐
相关产品推荐

