繁体   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