问题
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