簡體   English   中英

從泛型專業派生的普通類工廠

[英]Factory of plain classes derived from generic specializations

我有一個C#通用類B<T> 我也有一組派生類Di : B<Ti> 所有這些類始終使用相同的參數集創建。 因此,它導致了spagetti代碼:

if (typeof(T) == typeof(A1)) {work with D1}
else if (typeof(T) == typeof(A2)) {work with D2}
...

顯然,我想以如下方式重構代碼:

var dInst = GiveMeD<T>();
work with Di

如何實現GiveMeD<T>()函數?

更新:

work with Di >強制轉換為基類B<T>並使用其接口。 這里的主要問題-每個代碼塊在派生類構造函數調用上都不同。

如果要以這種方式有效地重構代碼,則必須考慮到“使用D1工作”和“使用D2工作”必須相同,並且僅行為必須有所不同。 也就是說,D1和D2必須具有一個公共的“接口”( B<T> ),並且您只能使用所說的“接口”,否則,您將再次在各處放置意大利面代碼,並且外觀很丑陋。

如果這符合您的需求(如果不符合,那么您應該重新考慮解決問題的整個方法),常見的模式是簡單地創建一個工廠方法,其中您的意大利面條式代碼將只編寫一次:

public static B<T> CreateD<T>()
{
    if (T is A1) return ... //here you can create a new instance of D1 or return a cached one, etc.
    else if (T is A2) return ...
}

當消費者不需要了解有關D1D2等的任何信息而僅需要了解B<T>時,我喜歡使用一個漂亮的模式:

public class B<T>
{
    public B<T> CreateD<T>()
    {
        if (T is A1) return ... //here you can create a new instance of D1 or return a cached one, etc.
        else if (T is A2) return ...
        ...
    }

    private B() { } //note constructor is private, consumer can't create a B<T>

    private class D1: B<A1> { ... } //private nested types, not visible outside B<T>.
    private class D2: B<A2> { ... }
}

現在,您可以完全控制可以實現的Di ,您公開了一個通用B<T>並且可以保證始終退還正確的專用類型,而無需使用戶真正了解它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM