【发布时间】:2011-10-31 16:17:44
【问题描述】:
//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% 的通用功能,但绑定/解除绑定可能非常具体。
这种泛型声明模式是否有一个名称,而不会将泛型暴露给最终用户?
【问题讨论】:
-
“关闭通用”对我来说听起来不错。
-
那么您究竟为什么要这样做?
-
好吧,例如,您可能有一组控制器,每个控制器都采用您的一个域类(或 DTO)并在 UI 中的视图上执行绑定/取消绑定/验证任务。此外,他们还必须知道如何检索和持久化这些对象。该持久性机制可能(IMO 应该)被很好地抽象,以便控制器可以使用相同的代码执行操作。但是,验证/绑定/解除绑定几乎肯定是非常特定于类的。
-
因此,您将定义一个具有通用持久性逻辑的 ControllerBase,然后在派生级别,因为您确切知道可以使用的类,关闭通用并指定您的特定类型逻辑。
标签: c# generics design-patterns