Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通用接口中的索引器 公共接口IRepository,其中T:EntityBase { T FindBy(对象键); 无效添加(T项); T此[对象键]{get;set;} 消除无效(T项); }_C#_.net_Generics_Interface - Fatal编程技术网

C# 通用接口中的索引器 公共接口IRepository,其中T:EntityBase { T FindBy(对象键); 无效添加(T项); T此[对象键]{get;set;} 消除无效(T项); }

C# 通用接口中的索引器 公共接口IRepository,其中T:EntityBase { T FindBy(对象键); 无效添加(T项); T此[对象键]{get;set;} 消除无效(T项); },c#,.net,generics,interface,C#,.net,Generics,Interface,这是“域驱动设计.NETC#”一书的作者给出的通用存储库接口的代码示例。作者在接口T this[object key]{get;set;}中放置了一个索引器,其中object key是对象ID(在整个系统中的标识)。作者指出,将索引器放在那里是为了强调存储库应该模拟内存中的对象集合。所以我的问题是:在接口中放置索引器有什么好处吗?任何链接、视频、书籍、教程都会对我有很大帮助。多谢各位 在这种情况下,索引器用于检索给定对象键(而不是集合中的索引)的对象。超出System.Collections.g

这是“域驱动设计.NETC#”一书的作者给出的通用存储库接口的代码示例。作者在接口
T this[object key]{get;set;}
中放置了一个索引器,其中object key是对象ID(在整个系统中的标识)。作者指出,将索引器放在那里是为了强调存储库应该模拟内存中的对象集合。所以我的问题是:在接口中放置索引器有什么好处吗?任何链接、视频、书籍、教程都会对我有很大帮助。多谢各位

在这种情况下,索引器用于检索给定对象键(而不是集合中的索引)的对象。超出System.Collections.generic中的标准通用接口,
IDictionary
是包含该功能的接口。但是,该接口包含更多存储库无法自然公开的功能

当然,可以实现这些其他方法,但效率不高。提供低效的API肯定会让API用户编写低效的代码

作者指出,索引器放在那里是为了强调 存储库应该模拟内存中的对象集合

老实说,我从未听说过这个概念。我在很多项目上看到了存储库模式的实现,但我们从未在那里使用过indexer。事实上,索引器将用于按ID获取项目,这将复制您的
T FindBy(对象键)

所以,我的总结是:在大多数情况下,存储库确实提供了对对象集合的访问,但我看不到向其中添加索引器的任何价值。我更愿意关注应用程序所需的事务/查询


我通常使用
BaseRepository:IRepository
实现generic
IRepository
,然后实现特定的存储库
UsersRepository:BaseRepository,IUsersRepository
其中
IUsersRepository
界面包含用于用户查询和命令的特定方法

作者指出,将索引器放在那里是为了强调存储库应该模拟内存中的对象集合

这听起来是一个合理的理由。通过“强调”一词,它指出了一个重要方面:索引器不一定添加任何功能,它也可以简单地用于提高生成代码的可读性

假设某个对象有一个名为
Resources
IRepository
类型的属性,在没有索引器的情况下,只能按如下方式检索特定项:

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); 
}
使用索引器,还可以执行以下操作:

var theItem = myObject.Resources.FindBy(someKey);
在某种程度上,这是个人偏好的问题,但第二个版本可能更直观地被识别为仅仅是从列表之类的东西中检索,而不是任意的参数化方法调用

在接口中放置索引器有什么好处吗

这是主观的。如果您发现通过某个键定位对象更有意义,为什么不呢

使用索引器时的主要问题是它们可能会过载。虽然您的接口定义了一个索引器来按id获取对象(其中id是
object
…我会将对象id转换为泛型类型…),但按照建议的模式,如果您定义的索引器多于按标识符检索域对象的索引器,则可能会失去索引器的意义

例如:

var theItem = myObject.Resources[someKey];
归根结底,实现索引器取决于您,在以正确的方式实现存储库方面,它不会或多或少地强调使用索引器:存储库可以在域和数据映射器之间进行调解,将域对象转换为数据,反之亦然。。也就是说,问题不在于方法的名称,也不在于它们看起来是否像IList


像集合一样工作并不意味着看起来像集合…

你说的“而不是IEnumerable或List”是什么意思?您可以展示使用索引器的这些替代方法吗?使用索引器并返回
IEnumerable
列表
是不同的事情,因为
T
不是一个集合。当给定一个已知键时,我想使用索引器,我可以检索它的值,或者给定一个键集它的值。也许你可以详细说明你的意思,而不是要求一个教程。我很抱歉我的免费信息。并不是要将IEnumerable或List放在那个上下文中。我在翻译中迷路了。我将编辑这个问题。谢谢你的耐心。嗯,如果你需要索引器,你可以放一个。我不理解这个问题。“在标准通用接口之外,
IDictionary
就是包含该功能的接口。”-根据您所称的“标准通用接口”,许多其他接口提供索引器,太多了。@O.R.Mapper编辑并更清楚地表明我指的是System.Collections.Generic接口。那么呢?它也有一个索引器。@O.R.Mapper请看我编辑的答案,索引器用于索引,而不是对象的键。
T this[object key] { get; set; }
T this[T someObject] { get; set; }
T this[int whoKnowsWhatIsIntegerHere] { get; set; }