可索引的界面

如果我只想索引一个类型的实例,应该使用什么C#接口? 我不需要(或想要)添加/删除/编辑元素的能力。 枚举是可以的。 这是否需要自定义IIndexable类型?

在这种情况下, IList是过度杀伤,因为它强制实施我不想拥有的成员。

IList<> (假设您希望保持通用)是包含索引器的唯一接口。

但是,您可以为所有那些您不想支持的操作显式实现并抛出NotSupportedException ,或者只实现IEnumerable<>并将其余部分仅放在类上,而不是在接口中。

从.Net 4.5开始,(可以说)正确的方法是使用IReadOnlyList ,它派生自IReadOnlyCollection ,它源自IEnumerable

  • IReadOnlyList为您提供索引器
  • IReadOnlyCollection为您提供集合Count属性。
  • IEnumerable为您提供集合枚举器。

它尽可能轻盈。

直接实现IReadOnlyList核心类:

  • List
  • Collection
  • ReadOnlyCollection
  • ArraySegment
  • T[]

您可以将其公开为IEnumerable并通过LINQ .Count.Count仍然具有索引行为。 如果底层集合支持IList ,则这些仍然是O(1)操作,因为LINQ足够智能以优化列表实现。 当然, .ElementAt并不像索引器那样简洁,但如果底层实现更改为不直接支持索引的集合,它还可以提供灵活性。 如果您不想使用此方法,则创建实现只读索引器的包装类并将所有调用委托给基础列表并不太困难。

为什么不只是IEnumerable<> +只有一个索引器的自定义界面?

为您定义可在界面中使用的自定义类

 public class Indexable { private readonly IList _innerList; public Indexable(IList innerList) { _innerList = innerList; } public T this[int index] { get { return _innerList[index]; } set { _innerList[index] = value; } } } 

用它作为

 public interface MyStuff { Indexable MyIndexableCollectionOfInt { get; } }