22

C# コンパイラは、メソッド呼び出しを解釈するときに、(静的) 引数の型を使用して、実際に呼び出されているオーバーロードを判断する必要があります。これをプログラムで実行できるようにしたい。

メソッドの名前 (a string)、それを宣言する型 (のインスタンス)、および引数の型のリストがある場合、標準ライブラリ関数を呼び出して、C# メソッドを表すオブジェクトSystem.Typeを取得できるようにしたいMethodInfoコンパイラは呼び出しを選択します。

たとえば、私が持っている場合

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

この場合methodToInvokepublic void myFunc(BaseClass bc).

:どちらの方法も私の目的には役立ちGetMethodません。GetMethodsどちらも過負荷の解決を行いません。その場合、GetMethod完全一致のみを返します。さらに派生した引数を与えると、単純に何も返されません。または、幸運にも、有用な情報を提供しないあいまいな例外が発生する場合があります。

4

1 に答える 1

8

答え

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)は、次の 2 つのパラメーターがあります。

  • 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です。

編集:これは堅牢です。

GetMethodparams、さらに派生したクラス、デリゲート、およびインターフェイスの実装を取る解決済みのメソッド。この 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 に答える