这种使用泛型的模式有名称吗?

发布于 2024-12-12 18:29:38 字数 1151 浏览 0 评论 0原文

//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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清音悠歌 2024-12-19 18:29:38

我相信这不是一种模式,而是 .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

又怨 2024-12-19 18:29:38

如果我要命名它,我会称之为具体,并且我同意阿利奥斯塔的观点,因为它是一种反模式。

If I were to name it, I would call it Specifics and I agree with Aliostad in that it is an anti-pattern.

梦里人 2024-12-19 18:29:38

泛型用于重用需要在类型之外进行描述的行为 - 或者至少在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文