Like Array是顺序内存分配,列表可能以与链表相同的方式存储在内存中(如果我错了,请纠正我)。 IEnumerable如何存储在c#的内存中? 假设我有一个班级
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
以下两种情况下内存分配如何不同。为什么编译器不允许我们编辑IEnumerables
IList<Employee> EmpList ;
Or
IEnumerables<Employee> EmpList ;
答案 0 :(得分:7)
这个问题无法回答。
这取决于实现IEnumerable
的基础对象。
它可能是一个数组,在这种情况下,内存表示只是一个数组,或者它可能是一个懒惰实现的枚举器,它按需生成值,在这种情况下它实际上没有其他内存表示而不是该方法中状态机的局部变量。
答案 1 :(得分:4)
IEnumerable变量存储一个对象引用(作为一个实现细节,它将是四个或八个字节,具体取决于进程)。 System.Collections.Generic.List变量,数组变量,ICollection变量或(尽管与问题无关)任何引用类型变量都是如此。
对象的枚举器生成的数据将被存储,但由参考点所指向的对象决定。在某些情况下,它将仅存储第一个元素以及枚举器用于计算后续元素的一些信息(例如,System.Linq.Enumerable.Range)。在其他情况下,对象可以是数组或SCGList(顺序存储 - 列表使用数组作为其存储),或链接列表,或散列集或排序集(分别使用散列表和二叉树) ,或者其他任何人想要梦想和实施的东西。
在关于内存分配的问题中,
之间的内存使用没有区别IList<Employee> empList = new List<Employee>();
和
IEnumerable<Employee> empList = new List<Employee>();
这两者之间的区别在于您可以从empList对象引用调用对象的方法。在第一种情况下,您仅限于IList中定义的许多成员及其继承的接口,因此您可以改变集合。在第二种情况下,您只能调用GetEnumerator,因此您无法改变集合。
答案 2 :(得分:2)
IEnumerable
只是一个接口,它应该做的只是
http://msdn.microsoft.com/en-us/library/cc317868.aspx
提供一个枚举器:
public IEnumerator GetEnumerator()
枚举者的实现可能不同, 事实上,它可能根本没有数据存储:
// Generates 0, 1, 2, ... sequence
public sealed class Sample: IEnumerable {
public IEnumerator GetEnumerator() {
for(int i = 0;; ++i)
yield return i;
}
}