繁体   English   中英

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

[英]How can I programmatically do method overload resolution in C#?

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

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

例如,如果我有

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

然后我想在System.Type上使用像虚构函数GetOverloadedMethod这样的东西

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

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

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

回答

使用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数组指定要获取的方法的参数列表。

从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 ,更多派生类,委托和接口实现的方法。 这个小提琴演示了所有这些案例 这是电话和他们检索的内容。

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

暂无
暂无

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

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