c# - 如何调用通用委托?
问题描述
这是来自我无法控制的外部库的代码:
public class Library {
public delegate void Handler<T>(in T type);
public void Subscribe<T>(Handler<T> handler) {
// Whatever...
}
}
这是我的应用程序代码:
public class Application {
public void Run() {
var library = new Library();
var types = new List<Type>() {typeof(int), typeof(string)};
foreach(var type in types) {
var methodLibrary = library.GetType().GetMethod("Subscribe");
var methodLibraryGeneric = methodLibrary.MakeGenericMethod(new Type[] {type});
var methodApplication = this.GetType().GetMethod("OnHandler", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var methodApplicationGeneric = methodApplication.MakeGenericMethod(new Type[] {type});
// [EXCEPTION] System.ArgumentException: method arguments are incompatible
var delegateApplication = Delegate.CreateDelegate(typeof(Library.Handler<>), methodApplicationGeneric);
methodLibraryGeneric.Invoke(library, new object[] {delegateApplication});
}
}
private void OnHandler<T>(in T type) {
// Whatever...
}
}
我希望很清楚我想要做什么:我有一大堆我在运行时确定的类型(不仅仅是用于演示目的的 int/string),我希望它们都注册到回调的外部库进入我的代码。
作为一种解决方法,我可以显式调用library.Subscribe<int>(OnHandler)
每种类型,但这会相当脆弱且容易出错,而且我认为泛型可以提供帮助。
解决方案
您应该创建构造委托类型的实例Handler<Something>
,而不是未绑定的Handler<>
。基本上,您应该调用MakeGenericType
on typeof(Handler<>)
,就像您对这两种方法所做的那样。您还需要传递this
to CreateDelegate
,因为methodApplicationGeneric
它不是静态方法。
var delegateApplication = Delegate.CreateDelegate(
typeof(Library.Handler<>).MakeGenericType(type),
this,
methodApplicationGeneric
);
推荐阅读
- c++ - dlclose 不释放库句柄以防访问静态类成员,例如调用 boost::this_fiber::get_id()
- bash - 自动 git clone 到一个唯一的目标目录
- typeorm - typeorm 多对多关系/带有复合键的一侧
- .net-core - 如果字符串包含作为数据传递给 rendera 的转义字符,则自适应卡片模板引擎会在 EXPAND 方法中中断
- python - 从数据表中删除行
- node.js - 如何同时更新 MongoDB 记录中的同一字段?
- c++ - 我们可以在 C++ 中使用包含类名的字符串来创建对象吗?
- git - 在使用 GitHub 进行托管时,是否可以在本地使用 Plastic SCM?
- html - div / 边框不随 img 缩放
- python - 在字符串上循环两次: