Индексируемый интерфейс
Какой интерфейс С# следует использовать, если я хочу только индексировать экземпляры типа? Мне не нужна (или не требуется) возможность добавлять/удалять/редактировать элементы. Перечисление в порядке. Требуется ли это для пользовательского типа IIndexable
?
В этом случае IList
является излишним, потому что он принудительно реализует элементы, которые я не хочу иметь.
Ответы
Ответ 1
IList<>
(при условии, что вы хотите оставаться родовым) является единственным интерфейсом для включения индексатора.
Однако вы можете просто реализовать и бросить NotSupportedException
для всех тех операций, которые вы не хотите поддерживать, или просто реализовать IEnumerable<>
, а остальные - только в классе, а не в интерфейсе.
Ответ 2
Начиная с .Net 4.5, возможно, правильный способ теперь использовать IReadOnlyList<T>
, который происходит от IReadOnlyCollection<T>
, который происходит от IEnumerable<T>
-
IReadOnlyList<T>
дает вам индекс
-
IReadOnlyCollection<T>
дает вам свойство Count Count.
-
IEnumerable<T>
предоставляет вам набор Enumerator.
Своего света, как вы можете это сделать.
Основные классы, которые непосредственно реализуют IReadOnlyList
:
Ответ 3
Вы можете представить его как IEnumerable<T>
и по-прежнему иметь поведение индексации через LINQ .ElementAt
и .Count
. Если базовая коллекция поддерживает IList<T>
, это все еще операции O (1), поскольку LINQ достаточно умен, чтобы оптимизировать реализацию списков. Конечно, .ElementAt
не так краток, как индекс, но также дает вам гибкость, если базовая реализация изменяется на коллекцию, которая не поддерживает прямую индексацию. Если вы не хотите использовать этот подход, создать класс-обертку, который реализует индексный модуль только для чтения, и не передавать все вызовы в базовый список, не так уж сложно.
Ответ 4
Почему не просто IEnumerable<>
+ настраиваемый интерфейс с помощью только индексатора?
Ответ 5
Определите для него пользовательский класс, который вы можете использовать в своем интерфейсе
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; }
}