是否有“空名单”? C# 中的单例?
在 C# 中,我经常使用 LINQ 和 IEnumerable。一切都很好(或者至少大部分如此)。
但是,在许多情况下,我发现自己需要一个空的 IEnumerable
作为默认值。也就是说,我想
for (var x in xs) { ... }
在不需要空检查的情况下工作。现在,这就是我目前所做的,具体取决于更大的上下文:
var xs = f() ?? new X[0]; // when xs is assigned, sometimes
for (var x in xs ?? new X[0]) { ... } // inline, sometimes
现在,虽然上面的内容对我来说完全没问题,也就是说,如果创建数组对象有任何“额外的开销”,我只是不在乎 - 我想知道:
C#/.NET 中是否有“空的不可变 IEnumerable/IList”单例?(即使没有,是否也有一种“更好”的处理方式上面描述的情况?)
Java 有 Collections.EMPTY_LIST
不可变的单例——通过 Collections.emptyList< T>()
—— 就是为了这个目的,尽管我不确定类似的概念是否可以在 C# 中工作,因为泛型的处理方式不同。
谢谢。
In C# I use LINQ and IEnumerable a good bit. And all is well-and-good (or at least mostly so).
However, in many cases I find myself that I need an empty IEnumerable<X>
as a default. That is, I would like
for (var x in xs) { ... }
to work without needing a null-check. Now this is what I currently do, depending upon the larger context:
var xs = f() ?? new X[0]; // when xs is assigned, sometimes
for (var x in xs ?? new X[0]) { ... } // inline, sometimes
Now, while the above is perfectly fine for me -- that is, if there is any "extra overhead" with creating the array object I just don't care -- I was wondering:
Is there "empty immutable IEnumerable/IList" singleton in C#/.NET? (And, even if not, is there a "better" way to handle the case described above?)
Java has Collections.EMPTY_LIST
immutable singleton -- "well-typed" via Collections.emptyList<T>()
-- which serves this purpose, although I am not sure if a similar concept could even work in C# because generics are handled differently.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您正在寻找
Enumerable.Empty()
。在其他新闻中,Java 空列表很糟糕,因为 List 接口公开了向列表添加元素的方法,这些方法会引发异常。
You are looking for
Enumerable.Empty<T>()
.In other news the Java empty list sucks because the List interface exposes methods for adding elements to the list which throw exceptions.
Enumerable.Empty()
正是如此。Enumerable.Empty<T>()
is exactly that.在原始示例中,您使用空数组来提供空枚举。虽然使用
Enumerable.Empty()
是完全正确的,但可能还有其他情况:如果您必须使用数组(或IList;
接口),您可以使用该方法来帮助您避免不必要的分配。
注释/参考:
In your original example, you use an empty array to provide an empty enumerable. While using
Enumerable.Empty<T>()
is perfectly right, there might be other cases: if you have to use an array (or theIList<T>
interface), you can use the methodwhich helps you to avoid unnecessary allocations.
Notes / References:
我认为您正在寻找
Enumerable。空()
。空列表单例没有多大意义,因为列表通常是可变的。
I think you're looking for
Enumerable.Empty<T>()
.Empty list singleton doesn't make that much sense, because lists are often mutable.
我认为添加扩展方法是一个干净的替代方案,因为它们能够处理空值 - 例如:
I think adding an extension method is a clean alternative thanks to their ability to handle nulls - something like:
对列表使用
Enumerable.Empty()
有一个缺点。如果将Enumerable.Empty
传递给列表构造函数,则会分配一个大小为 4 的数组。但是,如果您将空的Collection
传递给列表构造函数,则不会发生分配。因此,如果您在整个代码中使用此解决方案,那么很可能会使用其中一个 IEnumerable 来构造列表,从而导致不必要的分配。Using
Enumerable.Empty<T>()
with lists has a drawback. If you handEnumerable.Empty<T>
into the list constructor then an array of size 4 is allocated. But if you hand an emptyCollection
into the list constructor then no allocation occurs. So if you use this solution throughout your code then most likely one of theIEnumerable
s will be used to construct a list, resulting in unnecessary allocations.Microsoft 像这样实现了“Any()”(源)
如果您想在调用堆栈上保存调用,则无需编写调用
!Any()
的扩展方法,只需重写进行以下三项更改:Microsoft implemented `Any()' like this (source)
If you want to save a call on the call stack, instead of writing an extension method that calls
!Any()
, just rewrite make these three changes: