当参数是泛型时,Type.GetMethod 的类型数组中应包含哪些类型?
What Types should be in the Type array for Type.GetMethod when a parameter is generic?
如果我想通过反射调用泛型方法,我可以很容易地使用this技术,除非:
- 只能通过参数来区分该方法。
- 该方法有一个参数,其类型是该方法的类型参数之一。
如何在调用 Type.GetMethod(string, Type[])
时在 Type[]
数组中指定通用参数?
示例:
public class Example
{
//This is the one I want to call.
public void DoSomething<T>(T t) { ... }
public void DoSomething(Foo foo) { ... }
public void CallDoSomething(Type type, object value)
{
MethodInfo method = typeof(Example)
.GetMethod("DoSomething", new Type[] {/* what do i put here? */ });
MethodInfo generic = method.MakeGenericMethod(type);
generic.Invoke(this, value);
}
你可以这样做:
MethodInfo method = typeof(Example)
.GetMethods().First(mi => mi.Name == "DoSomething" && mi.IsGenericMethod);
根据您有多少方法重载,您可能必须使谓词更具体。
我会给你完整的 "thing" 我在必须找到 Queryable.Select<TSource, TResult> Method (IQueryable<TSource>, Expression<Func<TSource, TResult>>)
方法时使用的...它非常复杂并且检查几乎所有:
MethodInfo selectMethod = (from x in typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public)
where x.Name == "Select" && x.IsGenericMethod
let pars = x.GetParameters()
where pars.Length == 2
let args = x.GetGenericArguments()
where args.Length == 2 &&
pars[0].ParameterType == typeof(IQueryable<>).MakeGenericType(args[0]) &&
pars[1].ParameterType == typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(args))
select x).Single();
您可以轻松地将其用作模板。
请注意,未检查 return 类型,因为 return 类型没有重载。该方法是 static
和 public
的事实由 GetMethods()
检查。我检查参数数量、通用参数数量、参数类型。然后我使用 Single()
来确保只有一种方法。这应该是面向未来的:即使微软添加了另一个 Queryable.Select
方法,它也会是 "different".
在您的具体情况下:
MethodInfo method = (from x in typeof(Example).GetMethods(BindingFlags.Instance | BindingFlags.Public)
where x.Name == "DoSomething" && x.IsGenericMethod
let pars = x.GetParameters()
where pars.Length == 1
let args = x.GetGenericArguments()
where args.Length == 1 &&
pars[0].ParameterType == args[0]
select x).Single();
如果我想通过反射调用泛型方法,我可以很容易地使用this技术,除非:
- 只能通过参数来区分该方法。
- 该方法有一个参数,其类型是该方法的类型参数之一。
如何在调用 Type.GetMethod(string, Type[])
时在 Type[]
数组中指定通用参数?
示例:
public class Example
{
//This is the one I want to call.
public void DoSomething<T>(T t) { ... }
public void DoSomething(Foo foo) { ... }
public void CallDoSomething(Type type, object value)
{
MethodInfo method = typeof(Example)
.GetMethod("DoSomething", new Type[] {/* what do i put here? */ });
MethodInfo generic = method.MakeGenericMethod(type);
generic.Invoke(this, value);
}
你可以这样做:
MethodInfo method = typeof(Example)
.GetMethods().First(mi => mi.Name == "DoSomething" && mi.IsGenericMethod);
根据您有多少方法重载,您可能必须使谓词更具体。
我会给你完整的 "thing" 我在必须找到 Queryable.Select<TSource, TResult> Method (IQueryable<TSource>, Expression<Func<TSource, TResult>>)
方法时使用的...它非常复杂并且检查几乎所有:
MethodInfo selectMethod = (from x in typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public)
where x.Name == "Select" && x.IsGenericMethod
let pars = x.GetParameters()
where pars.Length == 2
let args = x.GetGenericArguments()
where args.Length == 2 &&
pars[0].ParameterType == typeof(IQueryable<>).MakeGenericType(args[0]) &&
pars[1].ParameterType == typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(args))
select x).Single();
您可以轻松地将其用作模板。
请注意,未检查 return 类型,因为 return 类型没有重载。该方法是 static
和 public
的事实由 GetMethods()
检查。我检查参数数量、通用参数数量、参数类型。然后我使用 Single()
来确保只有一种方法。这应该是面向未来的:即使微软添加了另一个 Queryable.Select
方法,它也会是 "different".
在您的具体情况下:
MethodInfo method = (from x in typeof(Example).GetMethods(BindingFlags.Instance | BindingFlags.Public)
where x.Name == "DoSomething" && x.IsGenericMethod
let pars = x.GetParameters()
where pars.Length == 1
let args = x.GetGenericArguments()
where args.Length == 1 &&
pars[0].ParameterType == args[0]
select x).Single();