36

在 C# 中获取类型化的只读空列表的标准方法是什么,或者有什么方法?

ETA:对于那些问“为什么?”的人:我有一个返回 an IList(或者更确切地说,post-answers,an IEnumerable)的虚拟方法,默认实现是空的。无论列表返回什么都应该是只读的,因为写入它将是一个错误,如果有人尝试这样做,我想立即停止并着火,而不是等待错误以某种微妙的方式出现。

4

8 回答 8

27

就个人而言,我认为这比其他任何答案都好:

static readonly IList<T> EmptyList = new T[0];
  • 数组实现IList<T>.
  • 您不能添加到数组。
  • 您不能分配给空数组中的元素(因为没有)。
  • 在我看来,这比new List<T>().AsReadOnly().
  • 你仍然可以返回一个IList<T>(如果你愿意的话)。

Enumerable.Empty<T>()顺便说一句,如果我没记错的话,这就是引擎盖下实际使用的东西。所以理论上你甚至可以这样做(IList<T>)Enumerable.Empty<T>()(尽管我认为没有充分的理由这样做)。

于 2011-07-23T20:04:53.817 回答
24

您可以创建一个列表:

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>

于 2010-10-08T22:38:31.683 回答
11

从 .net 4.6 开始,您还可以使用:

IList<T> emptyList = Array.Empty<T>();

这只会为您指定为 T 的每种不同类型创建一次新实例。

于 2016-10-06T09:23:04.033 回答
8
IList<T> list = new List<T>().AsReadOnly();

或者,如果你想要一个IEnumerable<>

IEnumerable<T> sequence = Enumerable.Empty<T>();
于 2010-10-08T22:38:45.940 回答
4

如果您想要一个内容无法修改的列表,您可以执行以下操作:

ReadOnlyCollection<Foo> foos = new List<Foo>().AsReadOnly();
于 2010-10-08T22:40:44.720 回答
2

System.Collections.ObjectModel.ReadOnlyCollection从您的列表中构造一个实例。

List<int> items = new List<int>();
ReadOnlyCollection<int> readOnlyItems = new ReadOnlyCollection<int>(items);
于 2010-10-08T22:40:57.460 回答
2

为了扩展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];
    }
}

编辑:我更改了上面的代码以反映与 Dan Tao 关于Instance字段的惰性初始化与急切初始化的讨论结果。

于 2012-05-18T20:09:06.527 回答
-1

关于什么:

readonly List<T> mylist = new List<T>();

不知道为什么你想要它只读;不过,在我能想到的大多数情况下,这没有多大意义。

于 2010-10-08T22:39:56.560 回答