简体   繁体   English

如何解决 C# 反射中的泛型方法歧义

[英]How to resolve generic method ambiguity in C# reflection

I have two generic method overloads, that differ by the number of generic type parameters and argument type我有两个泛型方法重载,它们的不同之处在于泛型类型参数和参数类型的数量

// Argument types
public class Bar<T> {}
public class Bar<T, U> {}

// Generic method overloads
private static void Foo<T> (Bar<T> b) {}
private static void Foo<T, U> (Bar<T, U> b) {}

I'm assuming that i can get the method info for either one by using the appropriate number of type parameters我假设我可以通过使用适当数量的类型参数来获取任何一个的方法信息

BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Static;

// Should give Foo<int>
GetType ().GetMethod ("Foo", Flags).MakeGenericMethod (typeof(int));

// Should give Foo<int, int>
GetType ().GetMethod ("Foo", Flags | BindingFlags.Static).MakeGenericMethod (typeof(int), typeof(int));

However this fails with System.Reflection.AmbiguousMatchException .但是,这失败了System.Reflection.AmbiguousMatchException

I tried specifying things like new Type[] {typeof (Bar<,>)} as the types argument for some of the GetMethod overloads, but the result was always null.我尝试将诸如new Type[] {typeof (Bar<,>)}之类的东西指定为某些GetMethod重载的types参数,但结果始终是 null。 I know i can workaround the ambiguity simply by using different names for the functions, but i'm interested to know if there's an actual solution to this.我知道我可以通过对函数使用不同的名称来解决歧义,但我很想知道是否有实际的解决方案。

I'm on .NET standard 2.0, .NET Core 2.0我在 .NET 标准 2.0,.NET 核心 2.0

If you don't want to use Type.GetMethods and iterate over the results you can use this overload of GetMethod and Type.MakeGenericMethodParameter which is available from .NET Core 2.1:如果您不想使用Type.GetMethods并迭代结果,您可以使用.NET Core 2.1 中提供的GetMethodType.MakeGenericMethodParameter重载:

class MyClass
{
    // Argument types
    public class Bar<T> { }
    public class Bar<T, U> { }

    // Generic method overrides
    private static void Foo<T>(Bar<T> b) { }
    private static void Foo<T, U>(Bar<T, U> b) { }
}

typeof(MyClass)
    .GetMethod(
    "Foo",
    1,
    BindingFlags.NonPublic | BindingFlags.Static,
    null,
    new[] { Type.MakeGenericSignatureType(typeof(MyClass.Bar<>), Type.MakeGenericMethodParameter(0)) },
    null
); // First Foo

typeof(MyClass)
    .GetMethod(
    "Foo",
    2,
    BindingFlags.NonPublic | BindingFlags.Static,
    null,
    new[] { Type.MakeGenericSignatureType(typeof(MyClass.Bar<,>), Type.MakeGenericMethodParameter(0),Type.MakeGenericMethodParameter(1)) },
    null
); // Second Foo

UPD UPD

Since Type.MakeGenericMethodParameter is not available for you the only option I see (if every method is not a part of generic class with the same generic type arguments) is to use GetMethods and filter the results.由于Type.MakeGenericMethodParameter对您不可用,我看到的唯一选择(如果每个方法都不是具有相同泛型类型参数的泛型 class 的一部分)是使用GetMethods并过滤结果。 Simplest filter in this case would be number of generic parameters;在这种情况下,最简单的过滤器将是泛型参数的数量;

var secondMethod = typeof(MyClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
    .Where(mi => mi.Name == "Foo" && mi.GetGenericArguments().Length == 2)
    .First();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM