[英]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 ...
}
当消费者不需要了解有关D1
, D2
等的任何信息而仅需要了解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.