0

我有许多MethodBase实例引用不同的开放通用方法(expected),例如代表以下方法:

T Foo<T>(T nevermind, T other);
T Foo<T>(string nevermind, T other);

我有一个MethodBase引用封闭方法的单个实例,该方法实际上被称为 ( actual),例如:

int Foo<int>(string nevermind, int other);

我如何以编程方式检查actual封闭方法是否可以匹配任何给定的expected开放方法,尤其是在考虑所有泛型陷阱和复杂性时?

具体来说,我想确定给定封闭方法的expected列表中的正确项目是而不是第二个。actualT Foo<T>(string nevermind, T other);

此外,对于MethodBase对应于 double Foo<double>(double something, string other)我希望没有匹配的结果。

遍历候选方法并检查每个参数expected是否可以从相应actual参数分配是一种好方法吗?如果是这样,这是最简单的方法吗?我是否需要考虑任何特殊情况以不匹配不会根据 .NET 中的方法重载解析规则选择的方法?

4

1 回答 1

1

Tl;博士。使用反射是不可能解决这个问题的,至少据我所知,而且没有更多的具体性..

方法解析规则极其复杂,尤其是对于泛型方法。你会陷入许多陷阱。您不仅需要知道方法、类型参数,还需要了解有关目标的大量信息,以及它自己的类型参数。在某些情况下,.

  • 方法在基类中有实现,但被子类隐藏。
  • 方法来自一个接口,并且是显式实现的,并且可能在实现者上有另一个同名的方法。
  • 除非您知道调用来自何处,否则无法消除诸如 、 和其他一些变体之类的方法的Foo<T>(T a, string other)歧义Foo<T>(string a, T other)(这些是合法的方法,并且被调用的方法取决于几件事)。Foo<T>(string a, string other)T = string
  • 通用约束可以放在方法上。
  • 参数类型的多态性,包括接口和委托的泛型变化。
  • 可选参数。
  • 这种情况一直在继续。

基本上,它永远无法工作。不使用反射。不是你提议的方式。即使您对可以拨打的电话有限制,您也必须决定检查哪些内容,哪些不检查,而且您总是会错过一些。顺便说一句,这些并不是唯一的陷阱,只是随机抽样。

但是,您确实有一些选择。

在我看来,第一个也是最好的选择是退后一步,思考最初的问题。如果可以,请发布。它可能有不同的答案,人们将能够为您提供更好的建议。希望理解起来不那么复杂。

如果你极大地限制了事情的范围,比如没有泛型约束、没有接口等等,这可能是可能的。这很容易出错,因为有很多陷阱。

您可以尝试在运行时使用动态绑定来解决它,但动态绑定解析方法的方式可能与通常发生的方式不同。不过,我对此知之甚少。

您可以挂钩运行时,也可以在解决方法调用时对其进行调查。有这方面的图书馆。这甚至可以让您了解后期绑定是如何解决的。

最后,您可以借助各种工具和库(例如Mono.Cecil. 在构建的库中,已经执行了方法解析,因此您将准确地看到从哪些位置调用了哪些方法。然而,这听起来并不可行。

哦,还有 Roslyn 和其他带有接口的编译器。他们已经实现了解析逻辑,因此他们可以使任务更容易。如果它们是开源的,您可以尝试了解如何在那里执行方法解析。不过,我有点超出我的深度。我怀疑这是不可行的。

我不喜欢发布指向特定库的链接,因为我宁愿你只是研究它们。也因为有很多选择。

总而言之,至少在我看来,并且根据我对问题的理解,如果没有对方法和更多信息的很大限制,这是不可能的。

于 2012-10-14T00:20:26.017 回答