2016-05-09 9 views
2

私は、ファイルからデータレコードを読み込み、読み取っているレコードのタイプに基づいてオブジェクトのリストを作成する必要があるアプリケーションを持っています。読み込み可能なレコードには6つのタイプがあります。私が指定したタイプのオブジェクトの作成を容易にするFileHelpersライブラリを発見しました。私はこのような方法で、1つのリーダー/ファイルパーサークラスが読み込んだレコードのすべての型を返すことを処理することができるようにしようとしています。これを行うには汎用のインターフェイス/メソッドを使用する可能性を模索していますが、それを正しく実装する方法。インタフェースのジェネリックメソッドを使用して、ファイルからの入力に基づいて変数タイプのリストを返す

私はReaderFactoryを持っており、特定のタイプのReaderを返し、すべてのReaderはMainReaderから継承します。

public interface MainReader<T> 
{ 
    void ReadFile(string vsFileName); 
    List<T> GetRecords(); 
} 


public class ReaderFactory<T> 
{ 
    MainReader<T> GetReader(RecordType recordType) 
    { 
     MainReader<T> oReader = null; 
     switch (recordType) 
     { 
      case RecordType.TypeA: 
       oReader = new TypeAReader(); 
       break; 
      case RecordType.TypeB: 
       oReader = new TypeBReader(); 
       break; 
     } 
    return oReader; 
} 

読者自身がファイルを取得し、FileHelpersライブラリを使用してデータをオブジェクトのリストに読み込みます。

class TypeAReader : MainReader<RecordTypeA> 
{ 
    public List<RecordTypeA> oRecordList = new List<RecordTypeA>(); 

    public void ReadFile(string fileName) 
    { 
     FileHelperEngine<RecordTypeA> oEngine = new FileHelperEngine<RecordTypeA>(); 
     RecordTypeA[] records = oEngine.ReadFile(fileName); 

     foreach(RecordTypeA record in records) 
     { 
      oRecordList.Add(record); 
     } 
    } 

    public List<RecordTypeA> GetRecords() 
    { 
     return oRecordList; 
    } 
} 

ビルド時に、「TypeReaderをMainReaderに暗黙的に変換できません」というエラーが表示されます。新しいTypeAReaderまたはTypeAReaderを返すようにファクトリを変更した場合、TypeReaderをMainReaderに変換できないという同じエラーが発生します。

私はこれを行う方法があると信じています、私は何かが欠けているに違いありません。どんな助力も非常に感謝しています。

+0

を防ぐために、インターフェイスにTを制限することによって、あなたの工場、いくつかの静的な型の保護を追加することができます必要なタイプ'oReader =(MainReader )new TypeAReader()' – igorushi

+0

既に汎用の 'FileHelperEngine {T}'を使用するのではなく、このクラスを作成するためのドライバは何ですか? –

+0

より多くの文脈を提供する場合などあなたの工場の消費者がRecordType値をどのように提供し、どのようにレコードのリストを消費するかによって、より良い設計を提案することができます。 – igorushi

答えて

1

コンパイルの問題について - キャストがありません:oReader =(MainReader<T>)new TypeAReader()は仕事をします。あなたはそれがコンパイルされない理由を理解したい場合は、次の呼び出しを考えてみます。

new ReaderFactory<int>().GetReader(RecodrTypeA) 

が明らか TypeAReader MainReader<int>インタフェースを実装していません。

ファクトリのデザインに関して、コンパイラは実際にはRecordType列挙型とTの間には関係がないことを暗示します。だから、最初にあなたがRECORDTYPE記述子を省略することができ、すべての:

public class ReaderFactory 
{ 
    MainReader<T> GetReader<T>() 
    { 
     var returnType = typeof(T); 
     if(returnType==typeof(RecordTypeB)) 
      return (MainReader<T>)new TypeBReader(); 
     if (returnType == typeof(RecordTypeA)) 
      return (MainReader<T>)new TypeAReader(); 
     throw new NotImplementedException(); 
    } 
} 

あなたもそれをキャストGetReader<int>()コール(まだ議論の余地)

interface IRecordType{} 
class RecordTypeA:IRecordType{} 
class RecordTypeB:IRecordType{} 
... 
MainReader<T> GetReader<T>() where T:IRecordType 
関連する問題