2015-02-05 62 views
2

問題:如何檢查T類型,其中T或者是ActionFuncMethodInfo比賽Delegate如何檢查MethodInfo是否匹配泛型類型T的委託,其中T是Action還是Func?

與得到所有靜態函數出 Assembly的用例

代碼示例,其匹配T類型的Delegate

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);   
      }     
     } 

    }   

功能調用示例:

var functions = new Dictionary<string, Func<int, int>>(); 
AddScriptFunctions(Assembly.GetExecutingAssembly(), functions); 

var functions2 = new Dictionary<string, Action>(); 
AddScriptFunctions(Assembly.GetExecutingAssembly(), functions2); 

:沒有將Delegate.CreateDelegate放入try/catch塊。

回答

2

您應該檢查簽名是否通過檢查參數和返回類型手動兼容。

例如下面的代碼檢查委託方法的賦值兼容性。這不限制爲ActionFunc;它將適用於任何代理類型。

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; 
} 

當然這段代碼並不考慮反轉;如果你需要這個工作反向工作,你需要檢查參數是否兼容分配,而不僅僅是等於(如我所做的那樣)。

遵循防禦性編程習慣,您可能需要驗證類型參數T以檢查它是否確實是委託類型。我把這個留給你。

相關問題