2016-05-09 1 views
2

У меня есть приложение, которое должно читать записи данных из файлов и создавать списки объектов на основе типа записи, которую он читает. Существует шесть возможных типов записей, которые можно прочитать. Я обнаружил библиотеку FileHelpers, чтобы облегчить создание объектов любого типа, который я указываю. Я пытаюсь написать это таким образом, что один класс читателя/файла парсера может обрабатывать возвращаемый тип записи любого типа. Я изучаю возможность использования общего интерфейса/метода для этого, но я как бы застрял на как правильно его реализовать.Использование универсального метода в интерфейсе для возврата списка типа переменной на основе ввода из файла

У меня есть ReaderFactory, который даст мне определенный тип 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; 
    } 
} 

При строительстве, я получаю ошибку «не может неявно преобразовать тип TypeAReader в MainReader». Если я изменю фабрику, чтобы вернуть новый TypeAReader или TypeAReader, я получаю ту же ошибку, что я не могу преобразовать TypeAReader в MainReader.

Я считаю, что есть способ сделать это, я должен просто что-то упустить. Любая помощь очень ценится.

+0

бросайте его требуемый тип, например '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(); 
    } 
} 

вы можете также добавить некоторые статические типа защиты вашего завода путем ограничения T с интерфейсом для предотвращения GetReader<int>() вызовов (до сих пор спорные)

interface IRecordType{} 
class RecordTypeA:IRecordType{} 
class RecordTypeB:IRecordType{} 
... 
MainReader<T> GetReader<T>() where T:IRecordType