可索引的界面

时间:2010-06-29 14:40:14

标签: c# interface

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

在这种情况下,IList过度,因为它会强制实施我不想要的成员。

5 个答案:

答案 0 :(得分:21)

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

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

它尽可能轻盈。

直接实现IReadOnlyList的核心类:

答案 1 :(得分:11)

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

public class Indexable<T>
{
    private readonly IList<T> _innerList;

    public Indexable(IList<T> innerList)
    {
        _innerList = innerList;
    }

    public T this[int index]
    {
        get { return _innerList[index]; }
        set { _innerList[index] = value; }
    }
}

将其用作

public interface MyStuff
{
    Indexable<int> MyIndexableCollectionOfInt { get; }
}