C# 如何检查MethodInfo是否匹配泛型类型T的委托,其中T是Action或Func?
问题:如何检查C# 如何检查MethodInfo是否匹配泛型类型T的委托,其中T是Action或Func?,c#,generics,reflection,delegates,C#,Generics,Reflection,Delegates,问题:如何检查MethodInfo是否与T类型的Delegate匹配,其中T是Action还是Func 代码示例,其用例是从程序集中获取所有静态函数,该程序集应与T类型的委托匹配: void AddScriptFunctions<T>(Assembly assembly, Dictionary<string, T> funMap) where T: class {
MethodInfo
是否与T
类型的Delegate
匹配,其中T
是Action
还是Func
代码示例,其用例是从程序集
中获取所有静态函数,该程序集应与T
类型的委托
匹配:
void AddScriptFunctions<T>(Assembly assembly, Dictionary<string, T> funMap) where T: class
{
foreach(Type type in assembly.GetTypes())
{
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
foreach(MethodInfo method in methods)
{
// How to check that MethodInfo can be converted into delegate of type T
// where T is Func<...> or Action<...>
if( ........ )
{
var function = (T)(object)Delegate.CreateDelegate(typeof(T), method);
funMap.Add(method.Name.ToLower(), function);
}
}
}
void AddScriptFunctions(程序集、字典funMap),其中T:class
{
foreach(在assembly.GetTypes()中键入Type)
{
var methods=type.GetMethods(BindingFlags.Public | BindingFlags.Static);
foreach(方法中的MethodInfo方法)
{
//如何检查MethodInfo是否可以转换为T类型的委托
//其中T是Func或Action
如果(……)
{
var function=(T)(object)Delegate.CreateDelegate(typeof(T),method);
Add(method.Name.ToLower(),函数);
}
}
}
函数调用示例:
var functions = new Dictionary<string, Func<int, int>>();
AddScriptFunctions(Assembly.GetExecutingAssembly(), functions);
var functions2 = new Dictionary<string, Action>();
AddScriptFunctions(Assembly.GetExecutingAssembly(), functions2);
var functions=newdictionary();
AddScriptFunctions(Assembly.getExecutionGassembly(),functions);
var functions2=新字典();
AddScriptFunctions(Assembly.getExecutionGassembly(),functions2);
注意:不要将
Delegate.CreateDelegate
包含在try/catch块中。您应该通过检查参数和返回类型手动检查签名是否兼容
例如,下面的代码检查要委派的方法的分配兼容性。这不会将类型限制为Action
或Func
;它将适用于任何委派类型
private void AddScriptFunctions<T>(Assembly assembly, Dictionary<string, T> funMap) where T : class
{
foreach (Type type in assembly.GetTypes())
{
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
foreach (MethodInfo method in methods)
{
if (IsMethodCompatibleWithDelegate<T>(method)))
{
var function = (T) (object) Delegate.CreateDelegate(typeof (T), method);
funMap.Add(method.Name.ToLower(), function);
}
}
}
}
public bool IsMethodCompatibleWithDelegate<T>(MethodInfo method) where T : class
{
Type delegateType = typeof(T);
MethodInfo delegateSignature = delegateType.GetMethod("Invoke");
bool parametersEqual = delegateSignature
.GetParameters()
.Select(x => x.ParameterType)
.SequenceEqual(method.GetParameters()
.Select(x => x.ParameterType));
return delegateSignature.ReturnType == method.ReturnType &&
parametersEqual;
}
private void AddScriptFunctions(程序集、字典funMap),其中T:class
{
foreach(在assembly.GetTypes()中键入Type)
{
var methods=type.GetMethods(BindingFlags.Public | BindingFlags.Static);
foreach(方法中的MethodInfo方法)
{
if(IsMethodCompatibleWithDelegate(方法)))
{
var function=(T)(object)Delegate.CreateDelegate(typeof(T),method);
Add(method.Name.ToLower(),函数);
}
}
}
}
公共bool是MethodCompatibleWithDelegate(MethodInfo方法),其中T:class
{
类型delegateType=typeof(T);
MethodInfo delegateSignature=delegateType.GetMethod(“调用”);
bool参数sequal=delegateSignature
.GetParameters()
.选择(x=>x.ParameterType)
.SequenceEqual(方法.GetParameters()
.选择(x=>x.ParameterType));
return delegateSignature.ReturnType==method.ReturnType&&
参数sequal;
}
当然,这段代码不考虑反向;如果需要反向工作,则需要检查参数是否与赋值兼容,而不仅仅是相等(如我所做的)
按照防御性编程实践,您可能需要验证类型参数T
,以检查它是否真的是委托类型。我将此留给您