2017-08-29 68 views
2

我想要使用反射來獲取接受Action<T>參數的方法定義。我正在使用.NET核心1.1。使用反射比較通用參數類型

由於該類有兩個具有相同名稱的方法,我試圖檢查接受的參數的類型,以確保我得到正確的方法定義(而不是其他重載),但比較似乎沒有工作。

下面是一些代碼,顯示了這個問題:

using System; 
using System.Linq; 
using System.Reflection; 

class ReflectMe { 
    public void SomeMethod<T>(Action<T> action) { 
     action(default(T)); 
    } 
    public T SomeMethod<T>() { 
     return default(T); 
    } 
} 

class Program { 
    static void Main(string[] args) { 
     var reflectedMethod = typeof(ReflectMe).GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance) 
      .Where(m => m.Name == "SomeMethod" && m.IsGenericMethodDefinition) 
      .Where(m => { 
       var parameters = m.GetParameters(); 
       if (parameters.Count() != 1) { 
        // this filters out the 1st method 
        return false; 
       } 
       var actionType = typeof(Action<>); 
       var parameterType = parameters[0].ParameterType; 
       if (parameterType == actionType) { 
        // this is always false, even if in the debugger both 
        // types are displayed as System.Action`1[T] 
        return true; 
       } 
       return false; 
      }) 
      .FirstOrDefault(); 
    } 
} 

的問題是,parameterTypeactionType是不相等的,但是當我在調試器中檢查它們看起來相同。

爲什麼比較失敗?

+0

你調試?你有**兩種**方法嗎?每種方法的**是什麼**'parameterType'? –

+0

調試我按預期得到了兩個方法,對於這兩個參數,參數類型都是Action'1 [T]。我更新了這個問題。 –

+0

動作<>!=動作,請參閱Titans答案 – bgura

回答

8

您需要實例的Action<T>的一般定義使用的方法的通用說法:

var methodTypeArg = m.GetGenericArguments().First(); 
var actionType = typeof(Action<>).MakeGenericType(methodTypeArg); 

注:我沒有.NET 1.1的核心得心應手,現在,我希望API是一樣的,但是你的問題在任何.NET版本中都是一樣的。

需要調用MakeGenericType變得更加明顯,如果你改變了通用參數的名稱的方法的原因:

public void SomeMethod<TMethodArg>(Action<TMethodArg> action) 

然後,它變得更加明顯,typeof(Action<>) != typeof(Action<TMethod>)。您正在使用定義的一個實例比較Action<>的一般定義(其中有它在T)的通用方法的通用參數(TMethodSomeMethod

+0

我認爲'動作'在方法定義中和'Action <>'實際上是一樣的。假如這個工作正常(謝謝!)有什麼需要使用泛型參數類型調用'MakeGenericType'? –

+2

@PaoloTedesco我給答案增加了一些解釋,希望事情更清楚。基本上typeof(Action <>)是泛型定義。參數不是這種類型,它們只能被定義爲定義的實例化,即使實例化本身與另一個泛型參數綁定。 –

+0

我現在明白了,是的,它完全合理。再次感謝 :) –