修订答案
好的,所以我想我已经弄清楚为什么该IsGenericParameter
属性评估为 false 是因为您正在创建具有显式类型的 MyClass 类型 for <T>
。
由于编译器新a
参数是什么类型(从类的实例化推断),我猜测编译器将参数视为非泛型类型。
另外,根据我在 MSDN 中阅读的内容,我认为ParameterType.IsGenericParameter和Type.IsGenericType 属性MyMethod<T>()
只有在你有类似vs.的方法时才会评估为 true MyMethod(T a)
,其中类型 for<T>
是从用类实例化的类型推断出来的.
这是一个小程序来演示这一点:
using System;
using System.Linq;
using System.Reflection;
namespace GenericParametersViaReflectionTest
{
class Program
{
static void Main(string[] args)
{
// Note: we're using the type without specifying a type for <T>.
var classType = typeof(MyClass<>);
foreach (MethodInfo method in classType.GetMembers()
.Where(method => method.Name == "MyMethod"))
{
// Iterate through each parameter of the method
foreach (var param in method.GetParameters())
{
// For generic methods, the name will be "T" and the FullName
// will be null; you can use which ever check you prefer.
if (param.ParameterType.Name == "T"
|| param.ParameterType.FullName == null)
Console.WriteLine("We found our generic method!");
else
Console.WriteLine("We found the non-generic method:");
Console.WriteLine("Method Name: {0}", method.Name);
Console.WriteLine("Parameter Name: {0}", param.Name);
Console.WriteLine("Type: {0}", param.ParameterType.Name);
Console.WriteLine("Type Full Name: {0}",
param.ParameterType.FullName ?? "null");
Console.WriteLine("");
}
}
Console.Read();
}
}
public class MyClass<T>
{
public void MyMethod(T a) { }
public void MyMethod(int a) { }
}
}
我们最终得到的结果是:
我们找到了还是通用的方法!
方法名称:MyMethod
参数名称:a
类型:T
类型全名:null
我们找到了非泛型方法:
方法名称:MyMethod
参数名称:a
类型:Int32
类型全名:System.Int32
如果您需要使用特定类型创建类的实例,您可能会发现Activator.CreateInstance 类也很有用。
原始答案
我认为,如果您传入与显式设置方法之一(例如 Int32 方法)匹配的相同数据类型的参数,那么编译器会自动选择接受泛型参数的参数。否则,编译器将选择泛型方法。
但是,如果您希望能够控制选择哪个方法,您可以修改每个方法以具有不同的参数名称,同时保持相同的签名,如下所示:
public class MyClass<T>
{
public void MyMethod(T genericA) {}
public void MyMethod(int intA) {}
}
然后,使用命名参数,您可以显式调用所需的方法,如下所示:
var foo = new MyClass<int>();
foo.MyMethod(genericA: 24); // This will call the "MyMethod" that only accepts <T>.
foo.MyMethod(intA: 19); // This will call the "MyMethod" that only accepts integers.
编辑
出于某种原因,在我的原始答案中,我错过了您提到使用反射的部分,但看起来我的原始答案可以与这些其他答案相结合,为您提供可行的解决方案: