ジェネリックメソッドを使用してインターフェイスでType.GetRuntimeMethodを呼び出すと、nullが返されます

Kzrystof

私は自分のC#プロジェクトの1つでリフレクションを使用しています。それはWindows8.1とWindowsPhone8.1を対象としたポータブルクラスライブラリです。

そのプロジェクトには、汎用パラメーターTGenericObjectを持つメソッドDoSomethingを持つIMyInterfaceという名前のインターフェイスがあります。MyClassという名前のクラスもあります。ある時点で、指定されたインターフェイスでメソッドDoSomethingをリフレクションによって検索する必要があります。そのため、実際のパラメーターの型(この例ではMyClass)を使用してTypeクラスのGetRuntimeMethodメソッドを使用しています。

ここで提供している例は、私が直面している問題を強調するためだけのものであることを忘れないでください。現実には、インターフェースIMyInterfaceとクラスMyClassは別のプロジェクトにあります。

これが取引です:GetRuntimeMethodがDoSomethingメソッドのMethodInfoを返すことを期待していましたが、そうではありませんでした:nullが返されます。

IMyInterfaceからDoSomethingメソッドを見つけるのに欠けている簡単なものはありますか、それとも手を汚す必要がありますか?

public interface IMyInterface
{
    void DoSomething<TGenericObject>(TGenericObject myGenericObject);
}

public class MyClass
{ }

class Program
{
    static void Main(string[] args)
    {
        MyClass myClassInst = new MyClass();

        MethodInfo methodInfo = typeof (IMyInterface).GetRuntimeMethod("DoSomething", new [] { myClassInst.GetType() });
    }
}
Kzrystof

GetRuntimeMethodメソッドに期待したことを実際に実行する独自の拡張メソッドをコーディングすることができました。気になるのは、.NETが提供するGetRuntimeMethodメソッドがサンプルでnullを返す理由がまだわからないことです。

これが私の問題を一時的に修正する不完全なクラスです。これは非常に素朴なアプローチですが、出発点です。そのクラスには欠けているものがたくさんありますが、少なくとも、それは私が続けることを可能にする答えです。

public static class TypeExtensions
{
    #region Public Methods

    /// <summary>
    /// Looks for the method in the type matching the name and arguments.
    /// </summary>
    /// <param name="type"></param>
    /// <param name="methodName">
    /// The name of the method to find.
    /// </param>
    /// <param name="args">
    /// The types of the method's arguments to match.
    /// </param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException">
    /// Thrown if:
    ///     - The name of the method is not specified.
    /// </exception>
    public static MethodInfo GetRuntimeMethod(this Type type, string methodName, Type[] args)
    {
        if (ReferenceEquals(type, null))
            throw new NullReferenceException("The type has not been specified.");

        if (string.IsNullOrEmpty(methodName))
            throw new ArgumentNullException("methodName", "The name of the method has not been specified.");


        var methods = type.GetRuntimeMethods().Where(methodInfo => string.Equals(methodInfo.Name, methodName, StringComparison.OrdinalIgnoreCase)).ToList();

        if (!methods.Any())
            return null;    //  No methods have the specified name.

        if (methods.Count == 1)
        {
            MethodInfo methodInfo = methods.Single();
            return IsSignatureMatch(methodInfo, args) ? methodInfo : null;
        }

        //  Oh noes, don't make me go there.
        throw new NotImplementedException("Resolving overloaded methods is not implemented as of now.");
    }

    #endregion

    #region Private Methods

    /// <summary>
    /// Finds out if the provided arguments matches the specified method's signature.
    /// </summary>
    /// <param name="methodInfo"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    private static bool IsSignatureMatch(MethodBase methodInfo, Type[] args)
    {
        Debug.Assert(!ReferenceEquals(methodInfo, null), "The methodInfo has not been specified.");


        //  Gets the parameters of the method to analyze.
        ParameterInfo[] parameters = methodInfo.GetParameters();

        int currentArgId = 0;

        foreach (ParameterInfo parameterInfo in parameters)
        {
            if (!ReferenceEquals(args, null) && currentArgId < args.Length)
            {
                //  Find out if the types matchs.
                if (parameterInfo.ParameterType == args[currentArgId])
                {
                    currentArgId++;
                    continue; //  Yeah! Try the next one.
                }

                //  Is this a generic parameter?
                if (parameterInfo.ParameterType.IsGenericParameter)
                {
                    //  Gets the base type of the generic parameter.
                    Type baseType = parameterInfo.ParameterType.GetTypeInfo().BaseType;


                    //  TODO: This is not good v and works with the most simple situation.
                    //  Does the base type match?  
                    if (args[currentArgId].GetTypeInfo().BaseType == baseType)
                    {
                        currentArgId++;
                        continue; //  Yeah! Go on to the next parameter.
                    }
                }
            }

            //  Is this parameter optional or does it have a default value?
            if (parameterInfo.IsOptional || parameterInfo.HasDefaultValue)
                continue; // Uhum. So let's ignore this parameter for now.

            //  No need to go further. It does not match :(
            return false;
        }

        //  Ye!
        return true;
    }

    #endregion
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

インターフェイスインスタンスを使用してジェネリックメソッドを呼び出す

分類Dev

ジェネリックスとのインターフェースでメソッドを呼び出す

分類Dev

インターフェイスで静的メソッドを使用して、インスタンス メソッドによって返されるジェネリック インスタンスを返すにはどうすればよいですか?

分類Dev

別のインターフェイスを使用して、インターフェイスからジェネリックメソッドを実装する

分類Dev

別のインターフェイスを使用して、インターフェイスからジェネリックメソッドを実装する

分類Dev

C#でMicrosoft Fakesを使用して、インターフェイスでジェネリックメソッド定義をスタブアウトする方法

分類Dev

別のdllのインターフェイスでImmutableArray <>を使用してメソッドを呼び出すと、System.MissingMethodExceptionがスローされます。

分類Dev

ワイルドカードを使用してジェネリックメソッドを呼び出すとコンパイルされません

分類Dev

C#ジェネリックでインターフェイスメソッド呼び出しが無視されるのはなぜですか?

分類Dev

ジェネリックメソッドを使用したインターフェイスの作成

分類Dev

ジェネリックメソッドでインターフェイス継承クラスを返す

分類Dev

SecretKeyで.getEncoded()を呼び出すと、nullが返されます

分類Dev

findViewById()をonCreate()で呼び出すと、nullが返されます。

分類Dev

null オブジェクト参照でインターフェイス メソッド sharedPreferences.edit()' を呼び出そうとしています

分類Dev

C#は、動的ではない非ジェネリック親インターフェイスからジェネリックインターフェイスメソッドを呼び出します

分類Dev

ジェネリッククラスでジェネリックリターンを使用してメソッドを呼び出すことが、javacによって安全でないと見なされるのはなぜですか?

分類Dev

ジェネリックリストマネージャー。比較メソッドを含むオブジェクトを使用して、Sortメソッドの比較インターフェースにアクセスできません

分類Dev

インターフェイスとして渡されたオブジェクトの埋め込まれたstructメソッドを呼び出す方法は?

分類Dev

インターフェイスメソッドがC#のジェネリック型パラメーターを使用して別のメソッドの型を返すようにすることは可能ですか?

分類Dev

インターフェイスでジェネリックを使用し、メソッドを繰り返します

分類Dev

リフレクションを使用してジェネリックメソッドを呼び出すときに「オブジェクトがターゲットタイプと一致しません」

分類Dev

ジェネリックメソッドを使用したジェネリックインターフェイスの実装

分類Dev

ジェネリックメソッドのバインドされた型パラメーターは、同等のジェネリックインターフェイスが機能しているときに失敗します。なぜですか?

分類Dev

ジェネリックメソッドのバインドされた型パラメーターは、同等のジェネリックインターフェイスが機能しているときに失敗します。なぜですか?

分類Dev

CLI / C ++インターフェイスクラス、テンプレートメソッドを呼び出すジェネリックメソッド

分類Dev

ジェネリックインターフェイスからメソッドを使用する

分類Dev

List <>メソッドを使用したJavaジェネリックインターフェイスでのコンパイラエラー

分類Dev

ジェネリックインターフェイスメソッドを正しく実装する方法は?

分類Dev

ジェネリックインターフェイスメソッドを実行する正しい方法は?

Related 関連記事

  1. 1

    インターフェイスインスタンスを使用してジェネリックメソッドを呼び出す

  2. 2

    ジェネリックスとのインターフェースでメソッドを呼び出す

  3. 3

    インターフェイスで静的メソッドを使用して、インスタンス メソッドによって返されるジェネリック インスタンスを返すにはどうすればよいですか?

  4. 4

    別のインターフェイスを使用して、インターフェイスからジェネリックメソッドを実装する

  5. 5

    別のインターフェイスを使用して、インターフェイスからジェネリックメソッドを実装する

  6. 6

    C#でMicrosoft Fakesを使用して、インターフェイスでジェネリックメソッド定義をスタブアウトする方法

  7. 7

    別のdllのインターフェイスでImmutableArray <>を使用してメソッドを呼び出すと、System.MissingMethodExceptionがスローされます。

  8. 8

    ワイルドカードを使用してジェネリックメソッドを呼び出すとコンパイルされません

  9. 9

    C#ジェネリックでインターフェイスメソッド呼び出しが無視されるのはなぜですか?

  10. 10

    ジェネリックメソッドを使用したインターフェイスの作成

  11. 11

    ジェネリックメソッドでインターフェイス継承クラスを返す

  12. 12

    SecretKeyで.getEncoded()を呼び出すと、nullが返されます

  13. 13

    findViewById()をonCreate()で呼び出すと、nullが返されます。

  14. 14

    null オブジェクト参照でインターフェイス メソッド sharedPreferences.edit()' を呼び出そうとしています

  15. 15

    C#は、動的ではない非ジェネリック親インターフェイスからジェネリックインターフェイスメソッドを呼び出します

  16. 16

    ジェネリッククラスでジェネリックリターンを使用してメソッドを呼び出すことが、javacによって安全でないと見なされるのはなぜですか?

  17. 17

    ジェネリックリストマネージャー。比較メソッドを含むオブジェクトを使用して、Sortメソッドの比較インターフェースにアクセスできません

  18. 18

    インターフェイスとして渡されたオブジェクトの埋め込まれたstructメソッドを呼び出す方法は?

  19. 19

    インターフェイスメソッドがC#のジェネリック型パラメーターを使用して別のメソッドの型を返すようにすることは可能ですか?

  20. 20

    インターフェイスでジェネリックを使用し、メソッドを繰り返します

  21. 21

    リフレクションを使用してジェネリックメソッドを呼び出すときに「オブジェクトがターゲットタイプと一致しません」

  22. 22

    ジェネリックメソッドを使用したジェネリックインターフェイスの実装

  23. 23

    ジェネリックメソッドのバインドされた型パラメーターは、同等のジェネリックインターフェイスが機能しているときに失敗します。なぜですか?

  24. 24

    ジェネリックメソッドのバインドされた型パラメーターは、同等のジェネリックインターフェイスが機能しているときに失敗します。なぜですか?

  25. 25

    CLI / C ++インターフェイスクラス、テンプレートメソッドを呼び出すジェネリックメソッド

  26. 26

    ジェネリックインターフェイスからメソッドを使用する

  27. 27

    List <>メソッドを使用したJavaジェネリックインターフェイスでのコンパイラエラー

  28. 28

    ジェネリックインターフェイスメソッドを正しく実装する方法は?

  29. 29

    ジェネリックインターフェイスメソッドを実行する正しい方法は?

ホットタグ

アーカイブ