首页 文章

如何以编程方式在C#中执行方法重载解析?

提问于
浏览
20

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

如果我有方法的名称( 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) .

NOTE :方法 GetMethodGetMethods 都不符合我的目的 . 他们都没有做任何重载决议 . 在 GetMethod 的情况下,它仅返回完全匹配 . 如果你给它更多的派生参数,它将只返回任何东西 . 或者你可能有幸得到一个模糊性异常,它没有提供有用的信息 .

1 回答

  • 4

    答案

    使用 Type.GetMethod(String name, Type[] types) 进行编程重载解析 . 这是一个例子:

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

    解释

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

    From the MSDN documentationType.GetMethod(String name, Type[] types) 有两个参数:

    • name 是要获取的方法的名称,和

    • types 提供方法参数的顺序,数量和类型 .

    运行代码

    Here is a running fiddle,演示程序化重载解析 .

    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 ,更多派生类,委托和接口实现的方法 . This Fiddle demonstrates all of those cases . 这是电话和他们检索的内容 .

    与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 在我们可能不期望工作的情况下执行重载解析 .

相关问题