2017-08-29 67 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

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