【发布时间】:2012-07-10 09:51:39
【问题描述】:
假设我有一个通用数据访问层,它应该支持不同的实现。为了实现这一点,我有一个基本接口IPeristenceService,它定义了访问持久层内数据的所有方法。界面可能如下所示:
public interface IPersistence
{
TData GetData<TData, TKey>(TKey Key);
}
因此持久化服务无法创建仅由其接口定义的对象实例,因此限制GetData-方法的实现是一个不错的决定:
public interface IPersistence
{
TData GetData<TData, TKey>(TKey Key) where TData : class, new();
}
这非常简单,因为实现此接口的开发人员在尝试返回接口指针时将无法编译他们的代码。持久层内部的数据需要用实现的对象来表示,而不是接口!
现在假设我们正在创建一个持久化服务,它将数据持久化到一个关系数据库中,由实体表示。所有实体都继承自一个基本接口:IEntity。传递非实体对象一定会失败,因为持久化服务只能持久化实体。所以我们需要验证传递的对象实例是否继承自IEntity。在编译时使用 where-notation 是可能的,但只需实现这样的接口:
public class DbPersistence : IPersistence
{
public TData IPersistence.GetData<TData, TKey>(TKey Key)
where TData : IEntity, class, new();
{
// fancy data access code
}
}
不起作用,是吗?!
有什么方法可以实现我想要做什么?
提前谢谢你:-)
【问题讨论】:
-
如果您可以将其设为运行时错误,您可以检查 Tdata 是否“是”IEntity。附带说明一下,利用现有的持久性框架(例如 NHibernate)不是更简单(不是专家,只是听说过它,听起来它会解决与您的代码相同的问题)吗?
-
是的,运行时验证是我目前解决这个问题的方法,但它们对于开发人员来说非常不直观且容易出错,因为他们需要调试应用程序。
标签: c# oop inheritance generic-constraints