C# / .NET equivalent for Java Collections.<T>emptyList()?

為{幸葍}努か 提交于 2019-12-18 11:41:05

问题


What's the standard way to get a typed, readonly empty list in C#, or is there one?

ETA: For those asking "why?": I have a virtual method that returns an IList (or rather, post-answers, an IEnumerable), and the default implementation is empty. Whatever the list returns should be readonly because writing to it would be a bug, and if somebody tries to, I want to halt and catch fire immediately, rather than wait for the bug to show up in some subtle way later.


回答1:


Personally, I think this is better than any of the other answers:

static readonly IList<T> EmptyList = new T[0];
  • Arrays implement IList<T>.
  • You cannot add to an array.
  • You cannot assign to an element in an empty array (because there is none).
  • This is, in my opinion, a lot simpler than new List<T>().AsReadOnly().
  • You still get to return an IList<T> (if you want).

Incidentally, this is what Enumerable.Empty<T>() actually uses under the hood, if I recall correctly. So theoretically you could even do (IList<T>)Enumerable.Empty<T>() (though I see no good reason to do that).




回答2:


You can just create a list:

List<MyType> list = new List<MyType>();

If you want an empty IEnumerable<T>, use Enumerable.Empty<T>():

IEnumerable<MyType> collection = Enumerable.Empty<MyType>();

If you truly want a readonly list, you could do:

IList<MyType> readonlyList = (new List<MyType>()).AsReadOnly();

This returns a ReadOnlyCollection<T>, which implements IList<T>.




回答3:


IList<T> list = new List<T>().AsReadOnly();

Or, if you want an IEnumerable<>:

IEnumerable<T> sequence = Enumerable.Empty<T>();



回答4:


Starting with .net 4.6 you can also use:

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

This does only create a new instance once for every different type you specify as T.




回答5:


If you want a list whose contents can't be modified, you can do:

ReadOnlyCollection<Foo> foos = new List<Foo>().AsReadOnly();



回答6:


Construct an instance of System.Collections.ObjectModel.ReadOnlyCollection from your list.

List<int> items = new List<int>();
ReadOnlyCollection<int> readOnlyItems = new ReadOnlyCollection<int>(items);



回答7:


To expand on Dan Tao's answer, the following implementation can be used in the same way as Enumerable.Empty<T>(), by specifying List.Empty<T>() instead.

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];
    }
}

Edit: I change the above code to reflect the outcome of a discussion with Dan Tao about lazy versus eager initialization of the Instance field.




回答8:


What about:

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

Not sure why you want it readonly; that doesn't make much sense in most scenarios I can think of, though.



来源:https://stackoverflow.com/questions/3894775/c-sharp-net-equivalent-for-java-collections-temptylist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!