这种使用泛型的模式有名称吗?
//this class (or interface if you like) is set up as generic...
public abstract class GenericBase<T>
{
public T PerformBasicTask(T in) { ... }
}
//... but is intended to be inherited by objects that close the generic...
public class ConcreteForDates:GenericBase<DateTime>
{
public DateTime PerformSpecificTask(DateTime in) { ... }
}
//... so that consuming code never knows that a generic is involved
var myDateConcrete = new ConcreteForDates(); //look ma, no GTP!
//These two methods look alike, and there is no generic type inference,
//even with PerformBasicTask().
var basicResult = myDateConcrete.PerformBasicTask(DateTime.Now);
var specificResult = myDateConcrete.PerformSpecificTask(DateTime.Today);
//does not compile because T is understood by inheritance to be a DateTime,
//even though PerformBasicTask()'s implementation may well handle an int.
var anotherBasicResult = myDateConcrete.PerformBasicTask(1);
我已经多次看到并使用过这种模式,它对于在一系列特定于类型的子类中提供通用功能非常有用。例如,这可能是特定于某种类型的域对象的控制器/演示者模型,该域对象是该类用于控制的页面的核心;诸如检索/持久化之类的基本操作可能会使用 100% 的通用功能,但绑定/解除绑定可能非常具体。
这种通用声明模式是否有一个名称,而不会将通用暴露给最终用户?
//this class (or interface if you like) is set up as generic...
public abstract class GenericBase<T>
{
public T PerformBasicTask(T in) { ... }
}
//... but is intended to be inherited by objects that close the generic...
public class ConcreteForDates:GenericBase<DateTime>
{
public DateTime PerformSpecificTask(DateTime in) { ... }
}
//... so that consuming code never knows that a generic is involved
var myDateConcrete = new ConcreteForDates(); //look ma, no GTP!
//These two methods look alike, and there is no generic type inference,
//even with PerformBasicTask().
var basicResult = myDateConcrete.PerformBasicTask(DateTime.Now);
var specificResult = myDateConcrete.PerformSpecificTask(DateTime.Today);
//does not compile because T is understood by inheritance to be a DateTime,
//even though PerformBasicTask()'s implementation may well handle an int.
var anotherBasicResult = myDateConcrete.PerformBasicTask(1);
I've seen and used this pattern several times, and it's very useful for providing common functionality across a series of type-specific subclasses. For instance, this could be a model for Controllers/Presenters specific to a type of domain object that is central to the page(s) the class is used to control; basic operations like retrieval/persistence may use 100% common functionality, but binding/unbinding may be very specific.
Is there a name for this pattern of generic declaration without exposing the generic to the end user?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我相信这不是一种模式,而是 .NET Framework 的泛型类型子系统的细节,该子系统通过用具体类型(在您的示例 DateTime 中)替换泛型类型参数来在运行时生成具体类型。与共享共同行为有关的所有其他事物都称为继承
I believe this is not a pattern but specifics of Generic Type subsystem of the .NET Framework which generates concrete type in runtime by substituting generic type parameter by a concrete type (in your example DateTime). All other things regarding sharing a common behaviour is known as Inheritance
如果我要命名它,我会称之为具体,并且我同意阿利奥斯塔的观点,因为它是一种反模式。
If I were to name it, I would call it Specifics and I agree with Aliostad in that it is an anti-pattern.
泛型用于重用需要在类型之外进行描述的行为 - 或者至少在
where
子句强制执行的限制范围内。恕我直言,您看到的示例是泛型反模式。类型应该不重要,或者即使重要,也只有在限制中定义时才重要 - 即
where
子句。所以基本上,一个期望所有子类实现抽象的通用抽象类不使用通用性。我不能简单地开始使用
Generic
这就是泛型的要点。我认为这违背了要点。
在这种情况下,使用通用抽象类/接口有一个轻微的好处,那就是
PerformSpecificTask
的类型安全实现。更新
我知道这是一个有争议的问题,我会被解雇,但我相信情况确实如此。
类可以愉快地对泛型类进行子类化并添加更多功能。但在这种情况下,正是额外的功能定义了该类的身份。当我不能只说
Generic
时,我就违背了泛型的目标。然而,有时,我关心的不是泛型——而是接口,这里似乎就是这种情况。更新2
一个经典的例子是.NET Framework 中的
IConvertible
。您可以为其设置一个通用接口/抽象类,并要求所有子类实现它,但框架将其设为可选情况,并且仅支持实现该接口的类。
Generics is used to re-use a behaviour that needs to be described beyond the type - or at least within the restrictions enforced by the
where
clause.The example you have seen, IMHO, is a generics anti-pattern. Type should not matter or if it does, should only matter if it is defined in the restrictions - i.e.
where
clause.So basically, a generic abstract class which expects all subclasses to implement an abstract, is not using the genericness. I cannot just simply start using
Generic<MyType>
which is the point of generics.I believe that defeats the point.
In this case there is a slight benefit in using a generic abstract class/interface and that is type safety achieve for
PerformSpecificTask
.UPDATE
I knew it is a contentious issue and I would be fired at left and right, but I believe it is the case.
A class can happily subclass a generic class and add more functionality. But in this case, it is the extra functionality that defines the identity of that class. When I cannot just say
Generic<MyOwnTypeOfVolition>
then I have defeated the objective of generics. Sometimes, however, it is not the generics which I am concerned with - it is the interface which seems to be the case here.UPDATE 2
A classic example, is
IConvertible
in .NET Framework.You could setup a generic interface/abstract class for it and ask all subclasses to implement it, but the framework makes it an optional case and supports it only for classes implementing the interface.