也许这是一个愚蠢的问题...但是创建常量IEnumerable<TSomeType>
的最佳(性能和内存方面)方法是什么? ...?
如果无法定义“最佳”方式,我有哪些选择?您的意见是什么,您认为有最合适的方法吗?
例如:
-
var enumerable = (IEnumerable<TSomeType>) new List<TSomeType> { Value1, Value2, Value3 };
-
var enumerable = (IEnumerable<TSomeType>) new TSomeType[] { Value1, Value2, Value3 };
- (其他一些选项;例如 Linq Select)。
请考虑到内存和性能是这里的一个问题 - 我们谈论的是一个真正受限的环境(安装了 .NET 的小型设备)。
提前致谢。
最佳答案
好吧,List<T>
数组也不是不可变的,所以如果你真的追求不变性,它们就会被淘汰 - 调用者可以转换结果然后修改它。
您可以创建一个 List<T>
并将其包装在 ReadOnlyCollection<T>
中.如果不再有对原始列表的引用,那么它实际上是不可变的,除非反射。
如果您实际上并不关心不变性 - 即,如果您相信所有代码都不会弄乱它 - 那么几乎可以肯定,数组将是性能最高的方法。有各种 CLR 级别的优化使它们工作得非常快。但是,在那种情况下,我不会转换为 IEnumerable<T>
- 我只是将它作为一个数组公开。与编译器必须调用 GetEnumerator()
相比,这将使迭代更快。 .
如果 C# 编译器看到 foreach
数组上的语句,它会生成调用以直接进入索引器并使用 Length
属性... 然后 CLR 也将能够删除边界检查,发现模式。
同样,如果您决定使用 List<T>
, 保留为 List<T>
- 这样你就可以使用 List<T>.Enumerator
- 这是一个结构 - 直接,没有装箱。
编辑:Steve Megson 提出了为此使用 LINQ 的要点。实际上,您可能会做得更好,因为一旦您获得了基础列表的枚举器,您就可以将 那个 安全地返回给调用者,至少对于我所知道的所有集合.所以你可以:
public class ProtectedEnumerable<T> : IEnumerable<T>
{
private readonly IEnumerable<T> collection;
public ProtectedEnumerable(IEnumerable<T> collection)
{
this.collection = collection;
}
public IEnumerator<T> GetEnumerator()
{
return collection.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
这意味着迭代时只有一个 微小 命中 - 只是对 GetEnumerator()
的单个委托(delegate)调用.与使用 Enumerable.Select
进行比较,这将需要在 每个 调用 MoveNext()
时接受额外的委托(delegate)(以及无操作投影)。
关于c# - 创建常量 IEnumerable<TSomeType>...的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4091451/