22

当 C# 编译器解释方法调用时,它必须使用(静态)参数类型来确定实际调用的是哪个重载。我希望能够以编程方式执行此操作。

如果我有方法的名称 (a string)、声明它的类型(的实例System.Type)和参数类型列表,我希望能够调用标准库函数并取回MethodInfo表示 C# 方法的对象编译器会选择调用。

例如,如果我有

class MyClass {
  public void myFunc(BaseClass bc) {};
  public void myFunc(DerivedClass dc) {};
}

然后我想要类似这个虚构功能GetOverloadedMethod的东西System.Type

MethodInfo methodToInvoke
  = typeof(MyClass).GetOverloadedMethod("myFunc", new System.Type[] {typeof(BaseClass)});

在这种情况下methodToInvoke应该是public void myFunc(BaseClass bc)

注意:这两种方法GetMethodGetMethods不会满足我的目的。他们都不做任何重载决议。在这种情况下,GetMethod它只返回完全匹配。如果你给它更多的派生参数,它只会返回任何东西。或者你可能很幸运地得到了一个不提供任何有用信息的模棱两可的异常。

4

1 回答 1

8

回答

用于Type.GetMethod(String name, Type[] types)执行编程重载解决方案。这是一个例子:

MethodInfo methodToInvoke = typeof(MyClass)
    .GetMethod("myFunc", new System.Type[] { typeof(BaseClass) });

解释

在示例中,methodToInvokemyFunc(BaseClass bc)不是myFunc(DerivedClass dc),因为types数组指定了要获取的方法的参数列表。

从 MSDN 文档Type.GetMethod(String name, Type[] types)有两个参数:

  • name是要获取的方法的名称,并且
  • types提供方法参数的顺序、数量和类型。

运行代码

这是一个演示程序重载解决方案的运行小提琴。

using System;
using System.Reflection;

public static class Program
{
    public static void Main()
    {
        MethodInfo methodToInvoke = typeof(MyClass)
            .GetMethod("myFunc", new System.Type[] { typeof(BaseClass) });

        var result = methodToInvoke
            .Invoke(new MyClass(), new object[] { new BaseClass() });

        Console.WriteLine(result);      
    }

    public class MyClass
    {
        public static string myFunc(BaseClass bc) {
            return "BaseClass";
        }

        public static string myFunc(DerivedClass dc) {
            return "DerivedClass";
        }
    }

    public class BaseClass { }
    public class DerivedClass : BaseClass { }
}

输出是BaseClass

编辑:这是健壮的。

GetMethod解析的方法采用params更多派生类、委托和接口实现。这个 Fiddle 演示了所有这些情况。这是电话和他们检索的内容。

适用于params

MethodInfo methodToInvoke2 = typeof(MyClass).GetMethod(
        "myFunc",
        new System.Type[] { typeof(Int32[]) });

将解决此方法

public static string myFunc(params int[] i)
{
    return "params";
}

适用于更多派生类

MethodInfo methodToInvoke3 = typeof(MyClass).GetMethod(
    "myFunc", 
    new System.Type[] { typeof(MoreDerivedClass) });

解析一个方法,该方法采用MoreDerivedClass

public class BaseClass { }
public class DerivedClass : BaseClass { }
public class MoreDerivedClass : DerivedClass {}

与代表合作

MethodInfo methodToInvoke4 = typeof(MyClass).GetMethod(
    "myFunc", 
    new System.Type[] { typeof(MyDelegate) });

... 将检索一个采用此委托的方法:

public delegate void MyDelegate(string x);

与接口实现一起工作

MethodInfo methodToInvoke5 = typeof(MyClass).GetMethod(
   "myFunc", 
   new System.Type[] { typeof(MyImplementation) });

...成功检索了一个方法MyImplementation

public interface IMyInterface {}
public class MyImplementation : IMyInterface {}

因此,它是健壮的,我们可以GetMethod在我们可能不希望工作的情况下使用重载解决方案。

于 2015-04-16T00:04:43.993 回答