Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检查MethodInfo是否匹配泛型类型T的委托,其中T是Action或Func?_C#_Generics_Reflection_Delegates - Fatal编程技术网

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
,以检查它是否真的是委托类型。我将此留给您