2011-07-15 11 views
0

C#でジェネリックメソッドを作成しようとしていますが、指定された型の配列が返されます。これは私の方法は、現時点では次のようになります。この型の配列を返す型パラメータを持つメソッド

private T[] GetKeys<T>(string key, Dictionary<string, object> obj) where T : new() 
{ 
    if (obj.ContainsKey(key)) 
    { 
     object[] objs = (object[])obj[key]; 
     T[] list = new T[objs.Length]; 
     for (int i = 0; i < objs.Length; i++) 
     { 
      list[i] = (T)Activator.CreateInstance(
          typeof(T), 
          new object[] { 
           (Dictionary<string, object>)objs[i] 
          }); 
     } 
     return list; 
    } 
    else 
    { 
     return null; 
    } 
} 

このクラスは内部的に使用し、私はすでにクラスは<T>に入れられますか知っているライブラリを使用して利用できませんされています。すべてのクラスはコンストラクタ内で同じパラメータを持ちます。しかし、このコードをコンパイルする前に、パラメータを持たないパブリックコンストラクタを与える必要がありました。今私がActivator.CreateInstance行になると、私はConstructor on type 'MyNamespace.MyClass+MyOtherClass' not foundと言うエラーが出ます。 MyClassは上記のメソッドを含むクラスです。 MyOtherClassは、Tとして渡されるクラスです。

ありがとうございましたありがとうございました!あなたはこれを使用していないので

T t = new T(); 

:これはT上の制約

private T[] GetKeys<T>(...) where T : new() 
             ↑ 

あなたはメソッド本体に次のようなコードを記述することができます:

答えて

2

これは、限り、あなたのコンストラクタは次のようになりますよう、あなたのために働く必要があります。

public MyType (Dictionary<string,object> dict) 
{ 
} 

をあなたのコンストラクタは非公開であれば、あなたはBindingFlags.NonPublicに渡すGetConstructorを変更する必要があります。

 private T[] GetKeys<T>(string key, Dictionary<string, object> obj) 
     // Since you're not using the default constructor don't need this: 
     // where T : new() 
     { 
      if (obj.ContainsKey(key)) 
      { 
       object[] objs = (object[])obj[key]; 
       T[] list = new T[objs.Length]; 
       for (int i = 0; i < objs.Length; i++) 
       { 
        list[i] = (T)typeof(T).GetConstructor(new [] {typeof(Dictionary<string,object>)}).Invoke (new object[] { 
             (Dictionary<string, object>)objs[i] 
            }); 
       } 
       return list; 
      } 
      else 
      { 
       return null; 
      } 
     } 
+0

理想的には、コンストラクタを内部にしたいと思います。しかし、私はGetConstructorに必要な追加パラメータの使い方に慣れていないので、現時点ではpublicコンストラクタを選択すると思います。 –

1

あなたGetKeys <T>はT must have a public parameterless constructorことが必要です特定の他のコンストラクタ(パブリックなパラメータのないコンストラクタのように強制することはできません)を期待して、制約を削除するだけで動作するはずです。

+0

ありがとうございました! –

0

あなたがこの方法のためのクラスに類似性を構築しているので、それはおそらくちょうどそれらすべてが(アプリケーションに適しているものは何でも、または同じ基本クラスを継承する)同じインターフェイスを拡張持つことが最善だろう。次に、基本クラスのリストを構築するために渡すコンストラクタパラメータを使用するだけです。次に、呼び出しコードで、適切なリスト項目をキャストできます。

+0

残念なことに、コンストラクタは、これらのクラス間の類似点が停止する場所です。これらは、このメソッドの実行ごとに完全に異なるキーを持つDictionaryオブジェクトに渡されます。クラスにも同様のプロパティやメソッドはありません。各クラスのコンストラクタは辞書を別々に調べ、処理します。 –