2009-06-17 7 views
3

実行時決定型パラメータを持つリスト<T>を生成しています。私は、リスト内の項目を反復処理するのForEachメソッドを呼び出すしたいと思います:C#:ランタイム生成リストでForEachを呼び出す<T>

//Get the type of the list elements 
Type elementType = GetListElementType(finfo); 

Type listType = Type.GetType("System.Collections.Generic.List`1[" 
           + elementType.FullName + "], mscorlib", true); 

//Get the list 
var list = getList.Invoke(null, new Object[] { finfo.GetValue(myObject) }); 

MethodInfo listForEach = listType.GetMethod("ForEach"); 

//How do I do this? Specifically, what takes the place of 'x'? 
listForEach.Invoke(list, new object[] { delegate (x element) 
          { 
           //operate on x using reflection 
          } 
         }); 

私の実行時に生成されたリストのタイプに含まれるのForEachメソッドに対応するMETHODINFO考えると、使用してそれを呼び出すための適切な方法は何ですか匿名の方法?上記は私の最初のスタブですが、匿名メソッドのパラメータの型を宣言する方法はわかりません。

答えて

4

あなたはこれを行うことができます。

var someGenericListYouCreated = ...; 
var enumerable = someGenericListYouCreated as IEnumerable; 

foreach(var foo in enumerable){ 
    ... 
} 

をしかし、私はあなたが実際にやりたい道に取り組んでいます。

編集:

右、私はこれはこれは何の意味

private class Adapter<T> 
{ 
    private readonly Action<object> act; 

    public Adapter(Action<object> act){ 
     this.act = act; 
    } 

    public void Do(T o) 
    { 
     act(o); 
    } 
} 

public static void Main(string[] args) 
{ 
    Type elementType = typeof(string); 

    var genericType = typeof(List<>).MakeGenericType(elementType); 
    var list = Activator.CreateInstance(genericType); 

    var addMethod = list.GetType().GetMethod("Add"); 
    addMethod.Invoke(list, new object[] { "foo" }); 
    addMethod.Invoke(list, new object[] { "bar" }); 
    addMethod.Invoke(list, new object[] { "what" }); 

    Action<object> printDelegate = o => Console.WriteLine(o); 

    var adapter = Activator.CreateInstance(typeof(Adapter<>).MakeGenericType(elementType), printDelegate); 
    var adapterDo = adapter.GetType().GetMethod("Do"); 

    var adapterDelegate = Delegate.CreateDelegate(typeof(Action<string>), adapter, adapterDo); 

    var foreachMethod = list.GetType().GetMethod("ForEach"); 

    foreachMethod.Invoke(list, new object[] { adapterDelegate }); 
} 

ます願っています:

  1. は、一般的なリストを作成します(これはtypeof演算(一覧<>を使っていることに気付く)
  2. このリストには一部の文字列を追加します
  3. 新しいdを作成しますelegate、この場合にはアクション
  4. はあなたドン、注意アダプタクラスに
  5. コールのForEach

を私たちが必要とするタイプ(アクション)のデリゲートを作成してアダプタクラス

  • のインスタンスを作成します。あなたが処理しようとしているタイプを知っていれば、必ずActionを使用しなければなりません。あなたは非常に簡単にアクションを使用することができ、それは動作します...

  • +0

    ニース。 +1私はそれが好きです。 –

    0

    ここにいくつかの問題があります。

    まず、文字列連結で型の名前を作成して、汎用パラメータを持つ型の型オブジェクトを取得するのはちょっと面倒です。代わりにこれを行う必要があります。

    Type genericType = typeof(List<>).MakeGenericType(new Type[] { listType }); 
    

    これはすっきりしています。今、このタイプのインスタンスのForEachメソッドを呼び出すには、Action<T>オブジェクトが必要です。あなたはラムダ式または関数ポインタを使用したい場合はそれは私のために完全に明白ではないのですが、ポイントはあなただけで、通常のパラメータと同様にAction<T>のインスタンスを渡すことです:あなたはの起源を明らかにすることができれば

    methodInfo.Invoke(list, new object[] { x }); 
    

    x(つまり、Action<T>パラメータ)を使用すると、さらに役立つ可能性があります。

    0

    私はあなたがのForEachが呼び出されたときに実行する定義されたメソッドを持っており、それが可能なデータ型にオーバーロードされます場合、それはジェネリックをされて使用

    class Program 
    { 
        static void Main(string[] args) 
        { 
         var sampleElement = "Foo"; 
    
         Type listType = typeof(List<>).MakeGenericType(sampleElement.GetType()); 
         Type actionType = typeof(Action<>).MakeGenericType(sampleElement.GetType()); 
    
         var list = Activator.CreateInstance(listType); 
         var action = Delegate.CreateDelegate(actionType, null, typeof(Program).GetMethod ("ForEach")); 
    
         (list as List<string>).AddRange (new []{ "1", "2" }); 
    
         listType.GetMethod ("ForEach").Invoke (list, new object []{ action }); 
        } 
    
        public static void ForEach(string item) 
        { 
         Console.WriteLine(item); 
        } 
    } 
    
    0

    を働くだろう、匿名メソッドが機能することを確認、しかしことができませんでしたなぜなら、ボクシングとアンボクシングなどを避けるため、理論的にはパフォーマンスが向上しているからです。しかし、リフレクションと非常に遅いメソッドを使用して、動的に作成されたジェネリックを使用する必要はありません。

    単純なIListインターフェイスとforeachループを使用しないのはなぜですか?

    +0

    これは良い点ですが、たとえば、非構造化データやランタイム作成クラスを扱う場合など、便利な場合があります。 – jonnii

    関連する問題