2014-09-11 5 views
3

Как Array - это последовательное распределение памяти, и список может храниться в памяти так же, как связанный список (пожалуйста, поправьте меня, если я ошибаюсь). Как IEnumerable хранится в памяти в C#? Предположим, у меня есть классКак IEnumerable хранится в памяти в C#?

public class Employee 
{ 
     public int Id { get; set; } 
     public string Name { get; set; } 
} 

Как распределение памяти будет отличаться в двух случаях ниже. почему компилятор не позволяет нам редактировать IEnumerables

IList<Employee> EmpList ; 

Or 

IEnumerables<Employee> EmpList ; 
+7

IEnumerable - это «интерфейс». Это в значительной степени зависит от конкретной реализации.'Array' и' LinkedList' также являются 'IEnumerable', но память, как вы указали, отличается. – 2014-09-11 06:42:53

+0

@pwas: ok, поэтому, когда я использую IEnumerable для хранения коллекции объекта, как компилятор использует для выделения памяти для него? это последовательное? или указатель на основе ссылок или что-то еще? –

+1

Это может быть или что-то еще, это зависит. Интерфейс ничего не подразумевает. –

ответ

3

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, поэтому вы не можете мутировать коллекцию.

6

Этот вопрос невозможно ответить.

Это зависит от базового объекта, который реализует IEnumerable.

Это может быть массив, и в этом случае представление памяти - это просто массив, или это может быть лениво реализованный перечислитель, который производит значения по требованию, и в этом случае на самом деле он не имеет представления памяти кроме локальных переменных конечного автомата в этом методе.

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; 
    } 
    } 
+1

Технически это хранит хотя бы «i», в экземпляре счетчика, созданного компилятором, и '. Current' value ...; p –

Смежные вопросы