泛型接口中的索引器
本文关键字:索引 泛型接口 | 更新日期: 2023-09-27 18:27:35
public interface IRepository <T> where T : EntityBase
{
T FindBy(object key);
void Add(T item);
T this[object key] { get; set; }
void Remove(T item);
}
这是一个通用存储库接口的代码示例,该接口由"Domain-Driven-Design .NET C#"一书的作者提供。作者在没有解释的情况下将索引器放在接口T this[object key] { get; set; }
其中对象键是对象 ID(就整个系统的标识而言(。作者指出,将索引器放在那里是为了强调存储库应模拟内存中的对象集合。所以我的问题是:将索引器放在接口中有什么好处吗?任何链接,视频,书籍,教程都会对我有很大帮助。谢谢。
作者指出,将索引器放在那里是为了强调 存储库应模拟内存中的对象集合。
老实说,我从未听说过这个概念。我在很多项目上看到了存储库模式的实现,我们从未在那里使用索引器。事实上,索引器将用于按 ID 获取项目,这将复制您的T FindBy(object key);
。
所以,我的总结:在大多数情况下,存储库确实提供了对对象集合的访问,但我看不到向其添加索引器的任何价值。我宁愿专注于您的应用程序所需的事务/查询。
我通常使用BaseRepository : IRepository<T>
实现通用IRepository<T>
,然后实现特定的存储库UsersRepository : BaseRepository<User>, IUsersRepository
IUsersRepository
其中接口包含用于用户查询和命令的特定方法。
在这种情况下,索引器用于检索给定对象的键(而不是它在集合中的索引(。在 System.Collections.Generic 中的标准通用接口中,IDictionary<TKey, TValue>
是包含该功能的接口。但是,该接口包含更多存储库不会自然公开的功能。
这些其他方法,但它们效率不高。提供低效 API 是邀请 API 用户编写低效代码的可靠方法。
作者指出,将索引器放在那里是为了强调存储库应模拟内存中的对象集合。
这听起来像是一个合理的理由。通过"强调"一词,它指向一个重要方面:索引器不一定添加任何功能,它也可以简单地用于提高结果代码的可读性。
假设某个对象具有名为 Resources
的属性,类型为 IRepository<Something>
,如果没有索引器,则只能按如下方式检索特定项:
var theItem = myObject.Resources.FindBy(someKey);
使用索引器,还可以执行以下操作:
var theItem = myObject.Resources[someKey];
在某种程度上,这是个人喜好的问题,但第二个版本可能更直观地识别为仅仅是从列表之类的东西中检索,而不是任意参数化的方法调用。
将索引器放在接口中有什么好处吗?
这是主观的。如果您通过某个键找到更有意义的定位对象,为什么不呢?
使用索引器时的主要问题是它们可能会过载。虽然您的接口定义了一个索引器以按 id 获取对象(其中 id object
...我会将对象 id 转换为泛型类型...(,按照建议的模式,如果您定义的索引器多于通过标识符检索域对象的索引器,则可能会丢失索引器的含义。
例如:
T this[object key] { get; set; }
T this[T someObject] { get; set; }
T this[int whoKnowsWhatIsIntegerHere] { get; set; }
归根结底,由您来实现索引器,它不会强调或多或少地以正确的方式实现存储库:当存储库在域和数据映射器之间进行调解以将域对象转换为数据时,存储库很好,反之亦然。也就是说,这与什么名称具有方法或它们是否看起来像IList<T>
无关......
像收藏一样工作并不意味着看起来像一个收藏......