如何调用通用委托?
How can I call a generic delegate?
这是我无法控制的来自外部库的代码:
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)
,但这相当脆弱且容易出错,我认为泛型可以提供帮助。
您应该创建 constructed 委托类型 Handler<Something>
的实例,而不是未绑定的 Handler<>
。基本上,您应该在 typeof(Handler<>)
上调用 MakeGenericType
,就像您对这两种方法所做的那样。您还需要将 this
传递给 CreateDelegate
,因为 methodApplicationGeneric
不是静态方法。
var delegateApplication = Delegate.CreateDelegate(
typeof(Library.Handler<>).MakeGenericType(type),
this,
methodApplicationGeneric
);
这是我无法控制的来自外部库的代码:
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)
,但这相当脆弱且容易出错,我认为泛型可以提供帮助。
您应该创建 constructed 委托类型 Handler<Something>
的实例,而不是未绑定的 Handler<>
。基本上,您应该在 typeof(Handler<>)
上调用 MakeGenericType
,就像您对这两种方法所做的那样。您还需要将 this
传递给 CreateDelegate
,因为 methodApplicationGeneric
不是静态方法。
var delegateApplication = Delegate.CreateDelegate(
typeof(Library.Handler<>).MakeGenericType(type),
this,
methodApplicationGeneric
);