2017-12-06 15 views
3

私の目標: 他のクラスの中から検索して実行できる特定のメソッドを含むC#スクリプトを他の人が追加できるようにするシステムがあります。ランタイム。タイプ変数を持つメソッドを動的に呼び出す

私のアプローチ: 私は、リフレクションを使用してインターフェイスを実装し、メソッド名はすべて、それらのクラスの間で同じにする必要があり、それらを一覧表示し、任意のクラスを通してので、私ができるループ方式とのインタフェースを作成しました。

ルックアップ中に見つかったすべてのクラスの列挙型を持つクラスがあり、ユーザーは実行時にそれらのクラスを選択できます。

これで、選択したクラスタイプのメソッドを取得してそのメソッドを呼び出すことができるようにする必要があります。問題は特定のメソッドの名前を知っていることですが、クラスのタイプは変数として保存されます。

コード:メモリから

//擬似コード:感謝

  //Possible solution 1: 
      Type selectedType = typeSelectedByEnum; 
      MethodInfo genericMethod = selectedType.GetMethod("TheInterfaceMethod").MakeGenericMethod(selectedType); 
      genericMethod.Invoke(selectedType, new object[0]); 

      //Possible solution 2: (however I would much prefer to use something avaliable prior to .NET 4.6) 
      Type selectedType = typeSelectedByEnum; 
      dynamic changedObj = Convert.ChangeType(selectedType, selectedType);//-Something here needs to implement IConvertable, how would I set this up? 
      changedObj.TheInterfaceMethod(); 

      //Possible solution 3: 

      //Your solution??! 

すべてのヘルプ、私は多くのことを試してみましたが、ただの可能性のあるランタイム代替約開いていているこの時点で。必要に応じてより多くのコードを提供することができます。

+0

:のは、あなたのインタフェースがIAwesomeInterfaceと呼ばれていると仮定しましょうか?ソリューション1ではどうなりますか?また、 'TheInterfaceMethod'はインスタンスメソッドですか?または静的メソッド?それがインスタンスメソッドの場合:どのオブジェクトを使用する必要がありますか?静的メソッドの場合:最初のパラメータに 'null'を渡します –

+0

選択リストに実際のオブジェクトを保持できますか?表示された名前を列挙型ではなく共通のインタフェースに置きます。次に、選択したオブジェクトから直接メソッドを呼び出すことができます。 – user6144226

+1

@ user6144226 nice;これらのオブジェクトが実際に 'List 'にあった場合、 'theList [(int)enumValue] .TheInterfaceMethod();' –

答えて

3

メソッド "TheInterfaceMethod"を持つクラスをマークするインターフェイスを使用しているので、メソッドは静的であってはなりません。つまり、メソッドを呼び出すオブジェクトのインスタンスが必要です。 Activatorクラスはオブジェクトのインスタンスを作成する簡単な方法を提供しますが、可視性を持つデフォルトのコンストラクタ(ほとんどの場合、あなたのケースではpublicコンストラクタ)が必要です。

「MakeGenericMethod」と呼んでいるあなたの例に潜在的な問題があることに気付きました。これは、関数に意味のある関数を定義するために必要なジェネリック型パラメータがある場合にのみ必要です。

interface IInterfaceWithGenericMethod 
    { 
     void TheInterfaceMethod<T>(); 
    } 

ここにあなたの変数を使用した例です:そのようなこのインタフェースとして

 Type selectedType = typeSelectedByEnum; 
     MethodInfo method = selectedType.GetMethod("TheInterfaceMethod"); 
     object obj = Activator.CreateInstance(selectedType); 
     method.Invoke(obj, null); 

あなたがオブジェクトのインスタンスを持っていたら面白いことに、あなたはもうメソッドを呼び出すためにリフレクションを必要としません。あなたは単にそれをあなたのインターフェイスにキャストすることができます。 ` - その後、あなたは解決策1で、既に持っているもの、あなたは`タイプselectedType = Type.GetType(fullTypeNameAsString)を探しているように、それは私には見えます

 Type selectedType = typeSelectedByEnum; 
     object obj = Activator.CreateInstance(selectedType); 
     IAwesomeInterface converted = obj as IAwesomeInterface; 
     converted.TheInterfaceMethod(); 
+0

アクティベーターが私が探していたものでした!うん、私はインターフェイスが静的ではないことを知っていたので、method.Invoke(null、null)はうまく動作せず、オブジェクトビットにハングアップしていました。これはうまくいった。 – FirefightGI

+0

リフレクションを使用している場合、インターフェイスを持つポイントは何ですか?この答えはインターフェイスの目的と完全に矛盾しています。 – Everts

+0

Btw、あなたはちょうどIInterfaceを行うことができますinterf = go.GetComponent (); if(interf!= null)interf.TheMethod(); – Everts

関連する問題