2012-11-27 63 views
6

我正在構建一個類似於此的通用平面文件閱讀器。我能否以某種方式整理這種(過度使用?)仿製藥?

public class GenericReader<TComposite, THeader, TData, TTrailer> 
    where TComposite : GenericComposite<THeader, TData, TTrailer>, new() 
    where THeader : new() 
    where TData : new() 
    where TTrailer : new() 
{ 
    public TComposite Read() 
    { 
     var composite = new TComposite(); 

     composite.Header = new THeader(); 
     composite.Data = new TData(); 
     composite.Trailer = new TTrailer(); 

     return composite; 
    }   
} 

它可以像這樣消耗。

var reader = new GenericReader<Composite<Header, Data, Trailer>, Header, Data, Trailer>(); 

var composite = reader.Read(); 
Console.WriteLine(composite.Data.SomeProperty); 

Console.ReadLine(); 

下面是使用的類。

public class Composite<THeader, TData, TTrailer> : GenericComposite<THeader, TData, TTrailer> 
{ 

} 

public class GenericComposite<THeader, TData, TTrailer> 
{ 
    public THeader Header { get; set; } 

    public TData Data { get; set; } 

    public TTrailer Trailer { get; set; } 
} 

public class Header { 
    public string SomeProperty { get { return "SomeProperty"; } } 
} 

public class Data { 
    public string SomeProperty { get { return "SomeProperty"; } } 
} 

public class Trailer { 
    public string SomeProperty { get { return "SomeProperty"; } } 
} 

有沒有辦法如何刪除或封裝GenericReader中的泛型類型信息?我正在尋找一雙額外的眼睛,向我展示我失蹤的事物。我們已經通過返回接口做了一些事情,並且讓消費者做了演員,但是這只是將責任推到了我認爲錯誤的位置,再加上性能會有小幅度的下降。

謝謝。

編輯:我不需要TComposite,我可以返回GenericComposite。我怎麼會錯過?

public class GenericReader<THeader, TData, TTrailer> 
    where THeader : new() 
    where TData : new() 
    where TTrailer : new() 
{ 
    public GenericComposite<THeader, TData, TTrailer> Read() 
    { 
     var composite = new GenericComposite<THeader, TData, TTrailer>(); 

     composite.Header = new THeader(); 
     composite.Data = new TData(); 
     composite.Trailer = new TTrailer(); 

     return composite; 
    }   
} 

public class GenericComposite<THeader, TData, TTrailer> 
{ 
    public THeader Header { get; set; } 

    public TData Data { get; set; } 

    public TTrailer Trailer { get; set; } 
} 
+2

你可能要檢查出[代碼審查SE(http://codereview.stackexchange.com/)。它真的更適合這樣的評論任務。 – tmesser

+3

我認爲這個問題符合SO;它不是一個代碼審查,它主要依賴的泛型類型參數的相互依存問題(和類型系統的談話絕對是話題的SO),並簡化了它.. – 2012-11-27 18:57:59

+0

對我的方式,你GenericReader聽起來更像是一個工廠然後是一個泛型類型,除非我失去了一些東西。聽起來像你會創建它只是爲了在之後處理它。那麼除了提供Composite之外,是否還有GenericReader存在的原因呢?複合材料是否有一些靜態方法來生成它自己的實例? – LightStriker

回答

2

有沒有辦法消除對您有一般約束的類型聲明的需要。

但是,你的使用情況表明,這是最常見的行爲:

var reader = new GenericReader<Composite<Header, Data, Trailer>, 
    Header, Data, Trailer>(); 

如果是這樣的話,在這裏你可以對與特定模式的使用頻率假設,你可以繼承從具有封閉類型定義的泛型類中選擇類型(或一組類型),可以更容易地使用它們。

在上述情況下,你可以爲基(以通用的定義,除)提供這些類,最常見的情況:

public class Composite : GenericComposite<Header, Data, Trailer> { } 

public class GenericReader : GenericReader< 
    Composite, Header, Data, Trailer> 
{ } 

這將然後像這樣被使用:

var reader = new GenericReader(); 

var composite = reader.Read(); 

Console.WriteLine(composite.Data.SomeProperty); 

Console.ReadLine(); 

你仍然必須使用通用的參數類型使用高度專業化的情況,但對於普通的用例(您通過分析/領域知識確定),您可以確定最常見的是什麼,並提供帶班設置類型參數來協助。

+0

這就是我現在正在做的。應該添加它到問題中。相當理智的解決方案! – JefClaes

+0

@JefClaes我最近有一種情況,我有三個泛型參數,其中兩個是常規用例,我發現爲我提供最適合我的是預先定義的類型參數(我推薦的)。也許是偶然的。 – casperOne

相關問題