Эквивалент С#/.NET для коллекций Java. <T> emptyList()?
Какой стандартный способ получить типизированный, только пустой список в С# или он есть?
ETA: Для тех, кто спрашивает "почему?": у меня есть виртуальный метод, который возвращает IList
(или, скорее, post-answers, a IEnumerable
), а реализация по умолчанию - пустой. Независимо от того, что возвращает список, нужно только читать, потому что запись на него будет ошибкой, и если кто-то попытается, я хочу немедленно остановиться и поймать огонь, а не дождаться появления ошибки каким-то тонким способом позже.
Ответы
Ответ 1
Лично я считаю, что это лучше, чем любой другой ответ:
static readonly IList<T> EmptyList = new T[0];
- Массивы реализуют
IList<T>
.
- Вы не можете добавить в массив.
- Вы не можете назначить элемент в пустом массиве (потому что его нет).
- Это, на мой взгляд, намного проще, чем
new List<T>().AsReadOnly()
.
- Вы по-прежнему можете вернуть
IList<T>
(если хотите).
Кстати, это то, что Enumerable.Empty<T>()
действительно использует под капотом, если я правильно помню. Поэтому теоретически вы даже можете сделать (IList<T>)Enumerable.Empty<T>()
(хотя я не вижу веских оснований для этого).
Ответ 2
Вы можете просто создать список:
List<MyType> list = new List<MyType>();
Если вы хотите пустую IEnumerable<T>
, используйте Enumerable.Empty<T>()
:
IEnumerable<MyType> collection = Enumerable.Empty<MyType>();
Если вам действительно нужен список только для чтения, вы можете сделать:
IList<MyType> readonlyList = (new List<MyType>()).AsReadOnly();
Это возвращает ReadOnlyCollection<T>
, который реализует IList<T>
.
Ответ 3
IList<T> list = new List<T>().AsReadOnly();
Или, если вы хотите IEnumerable<>
:
IEnumerable<T> sequence = Enumerable.Empty<T>();
Ответ 4
Начиная с .net 4.6 вы также можете использовать:
IList<T> emptyList = Array.Empty<T>();
Это создаст новый экземпляр только для каждого типа, который вы указываете как T.
Ответ 5
Если вам нужен список, содержимое которого не может быть изменено, вы можете сделать:
ReadOnlyCollection<Foo> foos = new List<Foo>().AsReadOnly();
Ответ 6
Чтобы расширить на ответ Dan Tao, следующую реализацию можно использовать так же, как Enumerable.Empty<T>()
, указав вместо этого List.Empty<T>()
.
public static class List
{
public static IList<T> Empty<T>()
{
// Note that the static type is only instantiated when
// it is needed, and only then is the T[0] object created, once.
return EmptyArray<T>.Instance;
}
private sealed class EmptyArray<T>
{
public static readonly T[] Instance = new T[0];
}
}
Изменить: я изменяю приведенный выше код, чтобы отразить результат обсуждения с Дэном Тао относительно ленивой и нетерпеливой инициализации поля Instance
.
Ответ 7
Создайте экземпляр System.Collections.ObjectModel.ReadOnlyCollection
из списка.
List<int> items = new List<int>();
ReadOnlyCollection<int> readOnlyItems = new ReadOnlyCollection<int>(items);
Ответ 8
Как насчет:
readonly List<T> mylist = new List<T>();
Не уверен, почему вы хотите его читать только; это не имеет большого смысла в большинстве сценариев, о которых я могу думать.