【发布时间】:2020-09-04 19:35:29
【问题描述】:
一切都在标题中,但让我放一些代码。 假设我们有一个包含两个同名方法的类:
class MyClass
{
/// <summary>
/// The first version
/// </summary>
public TItem Foo(long param1) { ... }
/// <summary>
/// Overload with a generic parameters
/// </summary>
public bool Foo<TItem>(out TItem item, long param1) { ... }
}
我们需要获取具有通用输出参数的第二个“Foo”方法的 MethodInfo:
public class AnotherClass
{
public MethodInfo GetFooForType(Type typeOfItem)
{
// the answer is probably GetMethod with the right parameters
return typeof(MyClass).GetMethod(???);
}
}
请注意:
- 我尝试不使用 GetMethods 或 GetMember,因为它不雅且容易出现未来错误
- 重命名任何 Foo 方法都不是一种选择(太容易了)。
- 类型或 TItem 显然只在运行时才知道。
- 我可能正在为 GetMethod 寻找正确的参数,但我可以接受任何建议(GetMethods 或 GetMember 除外)。
- 我花了 1 小时在 StackOverflow 上搜索答案,但没有成功,但反射发展得如此之快,以至于周围有很多不相关的答案。在 stackoverflow 中添加日期过滤器可能是个好主意(或者可能是 .Net 框架版本过滤器?)
- 非常欢迎您证明我错了,并找到我错过的明显答案!
- 这不是 .Net Core 项目(MakeGenericMethodParameter 不是一个选项)
- 我叫莫斯,我是个子弹瘾君子^^
【问题讨论】:
-
“...使用通用输出参数查找重载”可能会返回多个结果。最简单的机制是使用
GetMethods并过滤名称和参数,然后返回MethodInfo[]或返回MethodInfo,如果有多个与GetMethod相似的匹配项则返回异常。 -
第一个版本从哪里得到
TItem?我认为您需要为这两种方法提供更多上下文。 -
试试
type.GetMethod("Foo", new[] { Type.MakeGenericMethodParameter(0).MakeByRefType(), typeof(long) }) -
添加了更多上下文。我试图避免 GetMethod。 TItem 可以是任何东西,它是方法的通用参数,而不是声明类型。
-
我很确定您的问题(包括所有警告)的答案是“您不能那样做”。请参阅 2015 年 Marc Gravell 的 this answer。简短的版本是 Type.GetMethod 重载所需的类型仅存在于方法定义中。在您已经拥有该方法之前,您无法创建正确的泛型参数类型!如果您将 MyClass 设为泛型(例如
MyClass<TItem>),现在您可以使用 Type.GetMethod,因为现在您可以创建正确的泛型类型(根据@GuruStron 答案的第一部分) .
标签: c# generics reflection getmethod