改訂された回答
さて、IsGenericParameter
プロパティがfalseと評価される理由は、の明示的な型を使用してMyClass型を作成していたためだと思います<T>
。
コンパイラーはパラメーターの型を新しくしたのでa
(クラスのインスタンス化から推測)、コンパイラーはパラメーターを非ジェネリック型として扱っていたと思います。
また、MSDNで読んでいたことに基づいて、ParameterType.IsGenericParameterプロパティとType.IsGenericTypeプロパティMyMethod<T>()
は、 vs 。のようなメソッドがある場合にのみtrueと評価されると思いますMyMethod(T a)
。ここで、の型<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クラスも役立つ場合があります。
元の回答
明示的に設定されたメソッドの1つ(たとえば、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.
編集
何らかの理由で、私の元の回答では、リフレクションを使用して言及した部分を見逃しましたが、私の元の回答をこれらの他の回答と組み合わせて、実行可能な解決策を提供できるようです。