我正在尝试使用 MethodInfo 获取 Enumerable.SequenceEqualType.GetMethod(...) 。到目前为止,我已经尝试了以下方法:

var mi = typeof(Enumerable).GetMethod(nameof(Enumerable.SequenceEqual),
    BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Any,
    new Type[] { typeof(IEnumerable<>), typeof(IEnumerable<>) }, null);


var enumTyped = typeof(IEnumerable<>).MakeGenericType(ValueType);
var mi = typeof(Enumerable).GetMethod(nameof(Enumerable.SequenceEqual),
    BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Any,
    new Type[] { enumTyped, enumTyped }, null);

但是,这两种解决方案都返回 null 而不是我想要的方法。我知道该方法可以通过调用 GetMethods() 和过滤来检索,但我非常想知道如何使用 GetMethod(...) 检索它。

最佳答案

不幸的是,为了使用 Type.GetMethod(string name, Type[] types) 获得通用泛型方法,您必须在 Type[] 中为该方法提供正确的泛型类型,这意味着当您尝试这样做时:

Type requiredType = typeof(IEnumerable<>);
typeof(Enumerable).GetMethod("SequenceEqual", new Type[] { requiredType, requiredType });

你实际上需要做这样的事情:
Type requiredType = typeof(IEnumerable<TSource>);
typeof(Enumerable).GetMethod("SequenceEqual", new Type[] { requiredType, requiredType });

因为如果您查看 SequenceEqual 的签名,则泛型类型是 IEnumerable<TSource> 而不是 IEnumerable<>
public static IEnumerable<TSource> SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);

但是: 您无权访问 TSource 类型以使用它。
因此,获取 IEnumerable<TSource> 的唯一方法是使用如下所示的反射:
MethodInfo info = typeof(Enumerable)
    .GetMethods(BindingFlags.Static | BindingFlags.Public)
    .Where(x => x.Name.Contains("SequenceEqual"))
    .Single(x => x.GetParameters().Length == 2);
Type genericType = typeof(IEnumerable<>).MakeGenericType(infos.GetGenericArguments());

而不是使用
typeof(Enumerable).GetMethod("SequenceEqual", new Type[] { genericType, genericType });

但这需要我们无论如何都获得 SequenceEqual 方法 ,所以可悲的事实是,当使用 GetMethod 而不是 GetMethods 的重载很少时,使该方法成为通用方法实际上是不可能的*(您 可以 实现一个 Binder 并在GetMethod 方法,但它需要很长的编码,这可能会出现错误和不可维护,应该避免)。

关于c# - 如何获取 Enumerable.SequenceEqual 的 MethodInfo,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32776542/

10-11 01:39