如何以编程方式在 C# 中进行方法重载解析? [英] How can I programmatically do method overload resolution in C#?

查看:77
本文介绍了如何以编程方式在 C# 中进行方法重载解析?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When the C# compiler interprets a method invocation it must use (static) argument types to determine which overload is actually being invoked. I want to be able to do this programmatically.

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

If I have the name of a method (a string), the type that declares it (an instance of System.Type), and a list of argument types I want to be able to call a standard library function and get back a MethodInfo object representing the method the C# compiler would choose to invoke.

例如如果我有

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

然后我想要一个类似于 System.Type

Then I want something like this fictional function GetOverloadedMethod on System.Type

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

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

In this case methodToInvoke should be public void myFunc(BaseClass bc).

注意:GetMethodGetMethods 方法都不能达到我的目的.他们都没有做任何重载决议.在 GetMethod 的情况下,它只返回完全匹配.如果你给它更多的派生参数,它只会不返回任何内容.或者,您可能会幸运地得到一个不提供任何有用信息的歧义异常.

NOTE: Neither of the methods GetMethod and GetMethods will serve my purpose. Neither of them do any overload resolution. In the case of GetMethod it only returns exact matches. If you give it more derived arguments it will simply return nothing. Or you might be lucky enough to get an ambiguity exception which provides no useful information.

推荐答案

答案

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

Answer

Use Type.GetMethod(String name, Type[] types) to do programmatic overload resolution. Here is an example:

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

说明

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

Explanation

In the example, methodToInvoke will be myFunc(BaseClass bc) not myFunc(DerivedClass dc), because the types array specifies the parameter list of the method to get.

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

  • name 是要获取的方法的名称,并且
  • types 提供方法参数的顺序、数量和类型.
  • name is the name of the method to get, and
  • types provides the order, number, and types of the method's parameters.

这是一个正在运行的小提琴,演示了程序化的重载解析.

Here is a running fiddle that demonstrates programmatic overload resolution.

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 演示了所有这些情况.以下是调用及其检索的内容.

GetMethod resolved methods that take params, more derived classes, delegates, and interface implementations. This Fiddle demonstrates all of those cases. Here are the calls and what they retrieve.

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) });

... 将检索接受此委托的方法:

... will retrieve a method that takes this delegate:

public delegate void MyDelegate(string x);

与接口实现一起使用

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

... 成功检索到一个采用 MyImplementation

... successfully retrieves a method that takes MyImplementation

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

因此,它是健壮的,我们可以使用 GetMethod 来解决我们可能无法正常工作的重载解析.

So, it is robust, and we can use GetMethod to do overload resolution in cases that we might not expect to work.

这篇关于如何以编程方式在 C# 中进行方法重载解析?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆