Индексируемый интерфейс - PullRequest
18 голосов
/ 29 июня 2010

Какой интерфейс C # следует использовать, если я хочу иметь возможность индексировать только экземпляры типа? Мне не нужна (или не хочу) возможность добавлять / удалять / редактировать элементы. Перечисление в порядке. Требуется ли для этого пользовательский тип IIndexable?

В этом случае IList излишне, потому что это вызывает реализацию членов, которых я не хочу иметь.

Ответы [ 5 ]

22 голосов
/ 05 ноября 2014

Начиная с .Net 4.5 (возможно) правильным способом является использование IReadOnlyList<T>, которое происходит от IReadOnlyCollection<T>, которое происходит от IEnumerable<T>

  • IReadOnlyList<T> дает индексатор
  • IReadOnlyCollection<T> предоставляет свойство Count.
  • IEnumerable<T> дает вам перечислитель коллекции.

Это настолько легко, насколько вы можете сделать это.

Основные классы, которые непосредственно реализуют IReadOnlyList:

12 голосов
/ 29 июня 2010

IList<> (при условии, что вы хотите остаться универсальным) - единственный интерфейс, который включает индексатор.

Тем не менее, вы можете просто явно реализовать и выдать NotSupportedException для всех тех операций, которые вы не хотите поддерживать, или просто реализовать IEnumerable<> и оставить все остальное только в классе, а не в интерфейсе.

3 голосов
/ 29 июня 2010

Вы можете выставить его как IEnumerable<T> и по-прежнему вести индексирование через LINQ .ElementAt и .Count. Если базовая коллекция поддерживает IList<T>, это все еще операции O (1), поскольку LINQ достаточно умен, чтобы оптимизировать реализацию списка. Конечно, .ElementAt не так лаконичен, как индексатор, но также дает вам гибкость, если базовая реализация изменяется на коллекцию, которая не поддерживает индексацию напрямую. Если вы не хотите использовать этот подход, нетрудно создать класс-оболочку, который реализует индексатор только для чтения и делегирует все вызовы базовому списку.

1 голос
/ 29 июня 2010

Почему бы не просто IEnumerable<> + пользовательский интерфейс только с индексатором?

0 голосов
/ 09 февраля 2017

Определите собственный класс для него, который вы можете использовать в своем интерфейсе

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; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...