引用所需的重载泛型方法

sym*_*reg 13 c# generics reflection methodinfo

特定

public Class Example
{

public static void Foo< T>(int ID){}

public static void Foo< T,U>(int ID){}

}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 将其称为"重载通用方法"是否正确?
  2. 如何在创建MethodInfo对象时指定任一方法?

    Type exampleType = Type.GetType("fullyqualifiednameOfExample, namespaceOfExample");
    MethodInfo mi = exampleType.GetMethod("Foo", BindingFlags.Public|BindingFlags.Static, null, new Type[] {typeof(Type), typeof(Type) }, null);
    
    Run Code Online (Sandbox Code Playgroud)

参数4使编译器非常不满

Ray*_*Ray 13

我找不到一种方法来使用GetMethod做你想做的事.但是,您可以获取所有方法并浏览列表,直到找到所需的方法.

请记住,在实际使用之前,您需要调用MakeGenericMethod.

var allMethods = typeof (Example).GetMethods(BindingFlags.Public | BindingFlags.Static);
MethodInfo foundMi = allMethods.FirstOrDefault(
    mi => mi.Name == "Foo" && mi.GetGenericArguments().Count() == 2);
if (foundMi != null)
{
    MethodInfo closedMi = foundMi.MakeGenericMethod(new Type[] {typeof (int), typeof (string)});
    Example example= new Example();
    closedMi.Invoke(example, new object[] { 5 });
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*McG 5

以下是您问题的答案以及示例:

  1. 是的,尽管泛型方法有两件事需要注意:类型推断和重载方法解析。类型推断发生在编译时,编译器尝试解析重载方法签名之前。编译器将类型推断逻辑应用于共享相同名称的所有泛型方法。在重载解析步骤中,编译器仅包含那些类型推断成功的泛型方法。 更多这里...

  2. 请参阅下面的完整示例控制台应用程序代码,该代码显示了如何在创建 MethodInfo 对象时指定 Foo 方法的多个变体,然后使用扩展方法进行调用:

程序.cs

class Program
{
    static void Main(string[] args)
    {
        MethodInfo foo1 = typeof(Example).GetGenericMethod("Foo",
            new[] { typeof(string) },
            new[] { typeof(int) },
            typeof(void));

        MethodInfo foo2 = typeof(Example).GetGenericMethod("Foo",
            new[] { typeof(string), typeof(int) },
            new[] { typeof(int) },
            typeof(void));

        MethodInfo foo3 = typeof(Example).GetGenericMethod("Foo",
            new[] { typeof(string) },
            new[] { typeof(string) },
            typeof(void));

        MethodInfo foo4 = typeof(Example).GetGenericMethod("Foo",
            new[] { typeof(string), typeof(int) },
            new[] { typeof(int), typeof(string) },
            typeof(string));

        Console.WriteLine(foo1.Invoke(null, new object[] { 1 }));
        Console.WriteLine(foo2.Invoke(null, new object[] { 1 }));
        Console.WriteLine(foo3.Invoke(null, new object[] { "s" }));
        Console.WriteLine(foo4.Invoke(null, new object[] { 1, "s" }));
    }
}
Run Code Online (Sandbox Code Playgroud)

示例.cs:

public class Example
{
    public static void Foo<T>(int ID) { }
    public static void Foo<T, U>(int ID) { }
    public static void Foo<T>(string ID) { }
    public static string Foo<T, U>(int intID, string ID) { return ID; }
}
Run Code Online (Sandbox Code Playgroud)

扩展.cs:

public static class Extensions
{
    public static MethodInfo GetGenericMethod(this Type t, string name, Type[] genericArgTypes, Type[] argTypes, Type returnType)
    {
        MethodInfo foo1 = (from m in t.GetMethods(BindingFlags.Public | BindingFlags.Static)
                           where m.Name == name &&
                           m.GetGenericArguments().Length == genericArgTypes.Length &&
                           m.GetParameters().Select(pi => pi.ParameterType).SequenceEqual(argTypes) &&
                           m.ReturnType == returnType
                           select m).Single().MakeGenericMethod(genericArgTypes);

        return foo1;
    }
}
Run Code Online (Sandbox Code Playgroud)