C#:按类型的GetMethod(泛型列表)
我有一个包含几个泛型重载方法的类。我试图通过它的参数类型得到一个特定的参数。当我坚持使用前两个参数(使用int和string类型的参数)时,这相对容易做到。但无论我做什么,我都不能让我的程序注意到第三个,它是为通用列表设计的。我是否使用了错误的类型参数?如果是,正确的方法是什么C#:按类型的GetMethod(泛型列表),c#,system.reflection,C#,System.reflection,我有一个包含几个泛型重载方法的类。我试图通过它的参数类型得到一个特定的参数。当我坚持使用前两个参数(使用int和string类型的参数)时,这相对容易做到。但无论我做什么,我都不能让我的程序注意到第三个,它是为通用列表设计的。我是否使用了错误的类型参数?如果是,正确的方法是什么 /* rest of code */ static void Main(string[] args) { MethodInfo method = typeof(c).Get
/* rest of code */
static void Main(string[] args) {
MethodInfo method =
typeof(c).GetMethod("m", new Type[] { typeof(int) });
Console.WriteLine(method);
method =
typeof(c).GetMethod("m", new Type[] { typeof(String) });
Console.WriteLine(method);
method =
typeof(c).GetMethod("m", new Type[] { typeof(IEnumerable<>) });
Console.WriteLine(method);
Console.ReadKey();
}
}
static class c
{
public static void m<T>(int i)
{
}
public static void m<T>(String s)
{
}
public static void m<T>(IEnumerable<T> Ls)
{
}
}
/*代码的其余部分*/
静态void Main(字符串[]参数){
MethodInfo方法=
typeof(c).GetMethod(“m”,新类型[]{typeof(int)});
控制台写入线(方法);
方法=
typeof(c).GetMethod(“m”,新类型[]{typeof(String)});
控制台写入线(方法);
方法=
typeof(c).GetMethod(“m”,新类型[]{typeof(IEnumerable)});
控制台写入线(方法);
Console.ReadKey();
}
}
静态c类
{
公共静态无效m(int i)
{
}
公共静态void m(字符串s)
{
}
公共静态void m(IEnumerable Ls)
{
}
}
简短版本:typeof(IEnumerable)
与typeof(IEnumerable)
不同(对于某些T
)
更长的版本:没有方法void c.m(IEnumerable Ls)
,只有泛型参数为特定类型(运行时存在)的重载,其中由于某些代码引用泛型方法的实例化,抖动需要创建方法
在测试代码中向泛型方法的某个实例添加一个调用,然后对该实例执行GetMethod
考虑以下几点:
using System.Collections.Generic;
using System.Linq;
using static System.Console;
class Methods {
public static void M(int x) {
// no-op
}
public static void M<T>(IEnumerable<T> x) {
// no-op
}
}
class Program {
static void Main(string[] args) {
Methods.M(0);
Methods.M(new[] { "a", "b" });
ShowAllM();
}
public static void ShowAllM() {
var tm = typeof(Methods);
foreach (var mi in tm.GetMethods().Where(m => m.Name == "M"))
{
WriteLine(mi.Name);
foreach (var p in mi.GetParameters())
{
WriteLine($"\t{p.ParameterType.Name}");
}
}
}
}
使用System.Collections.Generic;
使用System.Linq;
使用静态系统控制台;
类方法{
公共静态void M(int x){
//无操作
}
公共静态void M(IEnumerable x){
//无操作
}
}
班级计划{
静态void Main(字符串[]参数){
方法:M(0);
方法:M(新的[]{“a”,“b”});
ShowAllM();
}
公共静态void ShowAllM(){
var tm=类型(方法);
foreach(tm.GetMethods()中的var mi,其中(m=>m.Name==“m”))
{
WriteLine(mi.Name);
foreach(mi.GetParameters()中的var p)
{
WriteLine($“\t{p.ParameterType.Name}”);
}
}
}
}
它产生输出:
M
Int32
M
IEnumerable`1
M
Int32
M
IEnumerable`1
注意,通用重载只产生一个结果。如果将对M(…)
的调用添加到Main
中,则输出相同
对于反射,只有一个方法,它的参数反映了它的“开放泛型”性质,但这与使用开放泛型类型(例如,IEnumerable
)调用并不完全相同,因为开放类型是不可实例化的
(我在这里捏造了很多技术细节。看看typeof(IEnumerable)
和typeof(IEnumerable)
在调试器中的区别是很有帮助的)简短版本:typeof(IEnumerable)
与typeof(IEnumerable)
(对于某些T
)
更长的版本:没有方法void c.m(IEnumerable Ls)
,只有泛型参数为特定类型(运行时存在)的重载,其中由于某些代码引用泛型方法的实例化,抖动需要创建方法
在测试代码中向泛型方法的某个实例添加一个调用,然后对该实例执行GetMethod
考虑以下几点:
using System.Collections.Generic;
using System.Linq;
using static System.Console;
class Methods {
public static void M(int x) {
// no-op
}
public static void M<T>(IEnumerable<T> x) {
// no-op
}
}
class Program {
static void Main(string[] args) {
Methods.M(0);
Methods.M(new[] { "a", "b" });
ShowAllM();
}
public static void ShowAllM() {
var tm = typeof(Methods);
foreach (var mi in tm.GetMethods().Where(m => m.Name == "M"))
{
WriteLine(mi.Name);
foreach (var p in mi.GetParameters())
{
WriteLine($"\t{p.ParameterType.Name}");
}
}
}
}
使用System.Collections.Generic;
使用System.Linq;
使用静态系统控制台;
类方法{
公共静态void M(int x){
//无操作
}
公共静态void M(IEnumerable x){
//无操作
}
}
班级计划{
静态void Main(字符串[]参数){
方法:M(0);
方法:M(新的[]{“a”,“b”});
ShowAllM();
}
公共静态void ShowAllM(){
var tm=类型(方法);
foreach(tm.GetMethods()中的var mi,其中(m=>m.Name==“m”))
{
WriteLine(mi.Name);
foreach(mi.GetParameters()中的var p)
{
WriteLine($“\t{p.ParameterType.Name}”);
}
}
}
}
它产生输出:
M
Int32
M
IEnumerable`1
M
Int32
M
IEnumerable`1
注意,通用重载只产生一个结果。如果将对M(…)
的调用添加到Main
中,则输出相同
对于反射,只有一个方法,它的参数反映了它的“开放泛型”性质,但这与使用开放泛型类型(例如,IEnumerable
)调用并不完全相同,因为开放类型是不可实例化的
(我在这里捏造了很多技术细节。查看typeof(IEnumerable)
和typeof(IEnumerable)
在调试器中的区别是很有帮助的)第三个方法的签名是m(IEnumerable)
,但您的示例显示了试图找到一个签名为m(IEnumerable)的方法的尝试。)
typeof(IEnumerable)
和typeof(IEnumerable)
之间的区别在于前者是泛型类型,第二个是泛型类型定义,它们不是一回事。泛型类型由泛型类型定义和泛型类型参数确定
考虑到这一点,您可能希望使用:
method =
typeof(c).GetMethod("m", new Type[] { typeof(IEnumerable<MyType>) });
方法=
typeof(c).GetMethod(“m”,新类型[]{typeof(IEnumerable)});
并替换将传递到方法中的枚举类型
另一方面,如果您事先不知道可枚举的类型,则可以获取泛型方法定义,并在需要时生成可用的泛型方法:
methodDef =
typeof(c).GetMethod("m", new Type[] { typeof(IEnumerable<object>) }).GetGenericMethodDefinition();
method = methodDef.MakeGenericMethod(new Type[] { typeof(MyType) });
methodDef=
typeof(c).GetMethod(“m”,新类型[]{typeof(IEnumerable)})。