2013-07-30 56 views
1

我目前正在研究一個C#程序,它從Excel文件中讀取測量數據,將它們解析爲對象並提供將它們插入數據庫的可能性(我使用NHibernate作爲此btw。)在C#中用泛型實現多態性

該程序將有一個GUI實現。有多種形式的測量數據。 (來自電動機的數據或來自交換機的數據)。問題是,我想只定義一個Form類(GUI窗口),而不管測量的數據是什麼進來的。

我有兩個解析器,MotorParser和SwitchboardParser,它們都有一個名爲的方法IList ParseDataTableToList(DataTable dataTable,DBConnectionWrapper dBCon)其中T是Motor對象或Switchboard對象。所以,我的想法是創建泛型接口,這將是這兩個類實現:

public interface IParser<T> 
{ 
    IList<T> ParseDataTableToList(DataTable dataTable, DBConnectionWrapper dBCon); 
} 

在另一方面,我確實有數據庫系統信息庫,其實現方法無效InsertOrUpdate(T列表),其中T再次是電機或交換機對象。我也實現了這個接口:

public interface IInsertOrUpdateList<T> 
{ 
    void InsertOrUpdate(IList<T> list); 
} 

好了,現在的想法是既轉發特定IInsertOrUpdateList對象(MotorRepository或SwitchboardRepository)和IParser(MotorParser或SwitchboardParser)。前面提到的Form類(我稱之爲ImportView)應該只能使用這些接口。問題是,我不知道在使用泛型時是否可行或如何實現。

這是我怎麼想好了這個執行無效的語法:

public partial class ImportView : Form 
{ 
    private IParser parser; 
    private IInsertOrUpdateList repository; 
    private dataToParse; 

    public ImportView(DataTable dataToParse, IParser parser, IInsertOrUpdateList repository) 
    { 
     this.parser = parser; 
     this.repository = repository; 
     this.dataToParse = dataToParse; 
    } 

    public void ParseAndInsertIntoDB() 
    { 
     repository.InsertOrUpdateList(parser.ParseDataTableToList(dataToParse, null)); 
    } 
} 

當我實例化這個窗口,我會提供確定這是否是測得的數據爲電機或總機對象的對象:

ImportView = new ImportView(dataToParse, new MotorParser(), new MotorRepository()); 

ImportView = new ImportView(dataToParse, new SwitchboardParser(), new SwitchboardRepository()); 

有沒有辦法我怎麼可以意識到泛型的問題,或者我的方法完全錯誤?我對任何想法都是開放的。

+0

你已經得到了什麼問題?看起來像一個好方法來做到這一點。只需使用工廠模式來創建你的'ImportView'。 – Belogix

+1

要更正語法,必須使'ImportView'類泛型:'ImportView ',然後使用類型'IParser '和'IInsertOrUpdateList '。不知道這是否足以使它編譯雖然... –

回答

1

有可能與仿製藥等來實現這一目標:

首先,你要爲你的解析器和庫泛型類:

  public class Parser<T> : IParser<T> 
      { 
       IList<T> ParseDataTableToList(DataTable dataTable, object o) 
       { 
        var list = new List<T>(); 
    //Your parsing logic can go: 
    //1) Here(using reflection, for example) or 
    //2) in the constructor for Motor/Switchboard object, 
    //in witch case they will take a reader or row object 
        return list; 
       } 
      } 
      public class Repo<T> : IInsertOrUpdateList<T> 
      { 
       void InsertOrUpdate(IList<T> list) 
       { 
        //... 
       } 
      } 

然後,你的通用窗口類看起來是這樣的:

public partial class ImportView<T> : Form 
{ 
    private IParser<T> parser; 
    private IInsertOrUpdateList<T> repository; 
    private DataTable dataToParse; 

    public ImportView(DataTable dataToParse) 
    { 
     this.parser = new Parser<T>(); 
     this.repository = new Repo<T>(); 
     this.dataToParse = dataToParse; 
    } 

    public void ParseAndInsertIntoDB() 
    { 
     repository.InsertOrUpdate(parser.ParseDataTableToList(dataToParse, null)); 
    } 
} 

你實例化它是這樣的:

var ImportView = new ImportView<Motor>(YourDataTable)