2011-02-05 8 views
8

リフレクションを使用してアイテムを一般リストに追加したいとします。 "DoSomething"メソッドでは、次の行を終了しようとしています。リフレクションを使用して一般リスト/コレクションにアイテムを追加する

エラーが発生しています。以下は

は私の完全なコード

public class MyBaseClass 
{   
    public int VechicleId { get; set; }   
}  
public class Car:MyBaseClass 
{ 
    public string Make { get; set; } 
}  
public class Bike : MyBaseClass 
{ 
    public int CC { get; set; } 
}   
public class Main 
{ 
    public string AgencyName { get; set; } 
    public MyBaseCollection<Car> lstCar {get;set;} 

    public void DoSomething() 
    { 
     PropertyInfo[] p =this.GetType().GetProperties(); 
     foreach (PropertyInfo pi in p) 
     { 
      if (pi.PropertyType.Name.Contains("MyBaseCollection")) 
      { 
       //Cln contains List<Car> 
       IEnumerable<MyBaseClass> cln = pi.GetValue(this, null) as IEnumerable<MyBaseClass>; 

       **//Now using reflection i want to add a new car to my object this.MyBaseCollection** 
       pi.PropertyType.GetMethod("Add").Invoke(??????) 
      } 
     }  
    } 
} 

任意のアイデア/提案ですか?あなたは何を知っていないので

// Cast to IEnumerable<MyBaseClass> isn't helping you, so why bother? 
object cln = pi.GetValue(this, null); 

// Create myBaseClassInstance. 
// (How will you do this though, if you don't know the element-type?) 
MyBaseClass myBaseClassInstance = ... 

// Invoke Add method on 'cln', passing 'myBaseClassInstance' as the only argument. 
pi.PropertyType.GetMethod("Add").Invoke(cln, new[] { myBaseClassInstance }); 

+0

MyBaseCollectionはどのようなタイプですか?リストに似ていますか? IEnumerableを実装するすべてのクラスでAddメソッドが保証されているわけではありません。 – JoeyRobichaud

+0

@JoeRobich:MyBaseCollectionはIList から派生した独自のコレクション実装です。リストの偶数回答は私の問題を解決するはずです... – kayak

答えて

18

のタイプのメソッドを呼び出しません。コレクションの要素型は(Car、Bike、Cycleなど)、役に立つキャストを見つけるのが難しいと思うでしょう。たとえば、コレクションはとなりますが、はに実装されていますが、これはすべて役立たず、IList<T>は共変できません。もちろん、IEnumerable<MyBaseClass>にキャストするとが成功するはずですが、突然変異をサポートしていないため、助けにならないでしょう。一方、コレクションタイプが非汎用型のIListまたはICollectionタイプを実装している場合は、それらへのキャストが便利になる可能性があります。

しかし、あなたは(つまり、あなたが事前にコレクションの要素型を知っている)コレクションがIList<Car>を実施することを確信しているならば、物事は簡単です:

// A much more useful cast. 
IList<Car> cln = (IList<Car>)pi.GetValue(this, null); 

// Create car. 
Car car = ... 

// The cast helped! 
cln.Add(car); 
+0

これはうまくいっています...、 – kayak

+0

IListにアイテムを追加することは間違いありませんが、 IEnumerable bcos..iにキャストを入力する必要があります。私はジェネリック型の基本クラスを持っています.. "IList cln =(IList )pi.GetValue(this、null);" ...あなたの最初の提案はうまくいきました... (他のコーディング要件のためにienumerableに変換しています) – kayak

+0

Ques://(要素型がわからない場合はどうしますか?) 答え:オブジェクトの別の場所から値を取得します階層....、実行時に派生クラスを作成していません。コードは、stackoverflow pruposeのサンプルです。(リアルタイムではより複雑です) – kayak

0

typeof<List<>>.GetMethodsでスタート、あなたは、プロパティの方法が、私はあなたが欲しいと思うプロパティ

0

は、あなただけのすべて一緒に反射を避けることができそして、使用:

List<MyBaseClass> lstCar { get; set; } 

lstCar.Add((MyBaseClass)new Car()); 
ます。また、インターフェイスや抽象メソッドを使用して検討することもでき

...

+0

私はいくつかの一般的な方法が必要です上記のコードはちょうどサンプル..私は多くのpruposesのためにそれを必要とする – kayak

+0

あなたは継承でこれを克服することができるはず、私は個人的に反射クラスとサブクラスが正しく構成されている場合は不要です。 – Rob

4

代わりに...ただしないでください。非ジェネリックのIListインターフェイスを考える:

IList list = (IList) {... get value ...} 
list.Add(newItem); 

それはのIListを実装するために、すべてのジェネリックコレクションのための義務はありませんが、それはコアフレームワークのコードのように多くのことを支えているので、彼らはほとんどすべて、やります。

+0

私はこれについて言及しましたが、私はOPのコレクションクラスは彼/彼女自身であると思います。この場合、非ジェネリックインターフェイスが実装されているかどうかは疑問です。 :) – Ani

関連する問題