如何从开放式泛型类型的开放式MethodInfo中获取已关闭的泛型方法?

8

想象一下这样的类型(C#):

public interface IAmGeneric<T>
{
   void SoAmI<T1>(T one, T1 two);
}

假设我有一个开放的泛型MethodInfo,来自类型的开放泛型版本(IAmGeneric<>.SoAmI<>()),以及以下数组

new[] { typeof(int), typeof(string) }'

我正在寻找一种高效可靠的方法来获取像这样的MethodInfo的封闭版本:
IAmGeneric<int>.SoAmI<string>()

更新:

我所说的“可靠性”是指它应该处理方法不是公共的情况,有十几个重载,使用基类型的通用参数,而不仅仅是它的直接接口等等。


如果您已经从接口中拥有了 MethodInfo,那么为什么还要关心基类型的重载和泛型参数呢?@DarrenKopp 的解决方案就是您所需要的。 - Marcel Gosselin
3个回答

1

像这样吗?不确定您要寻找什么,也许可以详细说明您的问题... 这肯定需要添加一些检查(例如检查声明类型是否为泛型/方法是否为泛型等)

var method = typeof(IAmGeneric<>).GetMethod("SoAmI");
var types = new[] { typeof(int), typeof(string) };


var methodTypeParams = method.GetGenericArguments();
var fullType = method.DeclaringType.MakeGenericType(types.Take(types.Length - methodTypeParams.Length).ToArray());
var fullMethod = fullType.GetMethod(method.Name).MakeGenericMethod(types.Skip(types.Length - methodTypeParams.Length).ToArray());

1

这里有一个相当复杂的案例需要正确处理:

public interface IAmGeneric<T>
{
    void SoAmI<T1, T2>(T one, T1 two, T2 three);
    void SoAmI<T1, T2>(T one, T2 two, T1 three);
    void SoAmI<T1, T2>(T1 one, T two, T2 three);
    void SoAmI<T1, T2>(T2 one, T1 two, T three);
    void SoAmI<T1, T2, T3>(T2 one, T1 two, T3 three);
}

对我来说,解决方案是使用GetMethods(...).Select()并比较方法名称、参数数量、类型和类型参数数量以找到正确的方法(基本上是方法签名的一部分)。

是的,那可能行得通,而且那正是我现在正在做的。然而性能远非卓越,因此我想知道是否有更好的方法。 - Krzysztof Kozmic

0
使用MethodBase.GetMethodFromHandle,如这个相关的答案所指出的:
var ty = typeof(IAmGeneric<>);
var numTyParams = ty.GenericTypeArguments.Length;
var mi = ... do something with ty to get generic def for SoAmI<> ...
var parameters = new[] { typeof(int), typeof(string) };
var output = MethodBase.GetMethodFromHandle(mi.MethodHandle, ty.MakeGenericType(parameters.Take(numTyParams).ToArray()).TypeHandle).MakeGenericMethod(parameters.Skip(numTyParams).ToArray());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接