2017-09-14 5 views
-1

タイトルが正しく書かれていない場合は、私に許してください。リストを反復処理して、Tが工場から返されたときに値にアクセスするにはどうすればよいですか

私は、さまざまなデバイスのデータベーステーブルからデータを取得してリストを作成しています。異なるデバイスは同じプロパティを持つことができ、異なるプロパティを持つことになりますので、実行時にFactory Patternを使用して作成します。

ファクトリクラス:

public interface IImportModel 
{ 
    IList CreateImportList(SqlDataReader reader); 
} 

とコンクリートクラス:

public class Device1ImportModel : IImportModel 
{ 
    public string SerialNumber { get; set; } 
    public string PartA { get; set; } 

    public IList CreateImportList(SqlDataReader reader) 
    { 
     Device1ImportModel linkedItem = new Device1ImportModel(); 

     List<Device1ImportModel> importList = new List<Device1ImportModel>(); 

     while (reader.Read()) 
     { 
      linkedItem = new Device1ImportModel(); 

      linkedItem.SerialNumber = reader["SerialNo"].ToString(); 
      linkedItem.PartA = reader["PartA"].ToString(); 

      importList.Add(linkedItem); 
     } 

     return importList; 
    } 
} 

私は工場からデバイスを作成します。

importModel = ImportModelFactory.CreateImportModel("Device1"); 

今、私はimportModelを反復処理したい場合、 item.SerialNumberにアクセスしようとした行にコンパイル時エラーが表示されます

foreach (var item in importList)     
{ 
     string number = item.SerialNumber; 
} 

エラー:

'object' does not contain a definition for 'SerialNumber' and no extension method 'SerialNumber' accepting a first argument of type 'object' could be found.

私はブレークポイントを配置し、アイテムの変数を上にマウスを移動した場合、私はプロパティと値を見ることができます。

varの代わりにdynamicを使用しましたが、後で私のコードでLinqやLambdaのクエリを使用できなくなりました。

  1. どのように値にアクセスできますか?
  2. おそらくReflectionを使用してIListをListに変換できますか?

編集1

CreateImportModelのためのコードを追加しました:

static public IImportModel CreateImportModel(DeviceType device) 
{ 
    switch (device) 
    { 
     case DeviceType.Device1: 
      return new Device1ImportModel(); 

     case DeviceType.Device2: 
      return new DeviceImportModel(); 

     default: 
      return null; 
    } 
} 
+0

'CreateImportModel'のソースコードを含めてください。 – mjwills

+0

すべてのデバイスタイプに 'SerialNumber'がありますか? – mjwills

答えて

2

変更List<Device1ImportModel>(またはIList<Device1ImportModel>またはIReadOnlyList<Device1ImportModel>)へIList

public List<Device1ImportModel> CreateImportList(SqlDataReader reader) 

IList古いインターフェース(事前ジェネリック)であり、したがって、あなたがIList(というよりもIList<Device1ImportModel)を使用する場合、コンパイラ/ランタイムは、あなたのデータのType(すなわちの概念を持っていませんそれは、このように、)objectとして扱い:に

public interface IImportModel<T> 
{ 
    List<T> CreateImportList(SqlDataReader reader); 
} 

とクラス::また、とのインタフェースを変更する必要があり

'object' does not contain a definition for 'SerialNumber' and no extension method 'SerialNumber' accepting a first argument of type 'object' could be found.

public class Device1ImportModel : IImportModel<Device1ImportModel> 
{ 
    public string SerialNumber { get; set; } 
    public string PartA { get; set; } 

    public List<Device1ImportModel> CreateImportList(SqlDataReader reader) 
    { 

あなたはおそらくもしたいですCreateImportModelを変更するので、代わりのようにそれを呼び出す:

ImportModelFactory.CreateImportModel("Device1"); 

あなたが代わりにそれが好き呼び出す:

ImportModelFactory.CreateImportModel<Device1ImportModel>(); 

コンクリートDevice1ImportModelが返され(したがってSerialNumberがアクセス可能である)ようにします。

+0

私のインターフェイスがIList CreateImportList(SqlDataReaderリーダー)に設定されているため、これは動作しません。私は複数の具体的なクラスを持っていて、どれが呼び出されているかを事前に知らないでしょう。 – Neill

+1

@Neillそのリストを反復し、具体的な型のうちの1つのみで見つかったプロパティを持つことを期待しています欠陥。すべての具体的な型が 'SerialNumber'を持っていれば、それをインタフェースの一部にして' List 'を使います。 – Rotem

+0

アップデートは@ニールに役立つのですか? – mjwills

3

あなたのメソッドのシグネチャを変更することができない場合は、あなたが使用することができます。

foreach (var item in importList.Cast<Device1ImportModel>())     
{ 
    string number = item.SerialNumber; 
} 

Device1ImportModelまたはその派生クラスではありませんimportList、コレクション内のオブジェクトが存在することになる場合、これは、しかし、例外がスローされます。

あなたは、リスト内のすべてのオブジェクトは、そのタイプのものであり、例外を回避したいことがわからない場合は、このapporachを使用します。

foreach (var item in importList.OfType<Device1ImportModel>())     
{ 
    string number = item.SerialNumber; 
} 
+0

私はどのクラスを呼び出すのか事前に分かりません。 – Neill

+1

@Neill、どのクラスを期待するのかわからない場合は、 'SerialNumber'プロパティがあることをどのように確認できますか?あなたの問題には解決策がありません。 – dymanoid

+0

すべてのクラスには常にあるプロパティがあります。 SerialNumberはその1つです。 – Neill

0

私はすべてのプロパティを保持するために別のクラスを使用して終了、それぞれの具体的なクラスがそれを使用するかどうかは関係ありません。

その理想的ではなく作品ではありません。

でも、私はそれ自身の性質の原因であると各具象クラスに頼る好適だろう。

関連する問題