Разница между списками и последовательностями - PullRequest
2 голосов
/ 13 апреля 2010

Я пытаюсь понять разницу между последовательностями и списками.

В F # есть четкое различие между ними. Однако в C # я видел, как программисты ссылаются на коллекции IEnumerable как последовательность. Является ли то, что делает IEnumerable последовательностью тот факт, что он возвращает объект для перебора коллекции?

Может быть, настоящее различие чисто в функциональных языках?

Ответы [ 3 ]

7 голосов
/ 13 апреля 2010

Не совсем - вы склонны иметь произвольный доступ к списку, а также иметь возможность быстро получить его счет и т. Д. По общему признанию связанные списки не имеют характера произвольного доступа ... но тогда они не реализуются IList<T>. Между объектами, предоставляемыми конкретной платформой, и общими понятиями есть серая область.

Последовательности (обозначенные IEnumerable<T>) предназначены только для чтения, только для пересылки, по одному элементу за раз и потенциально бесконечны. Конечно, любая реализация последовательности также может быть списком (например, List<T>), но когда вы обрабатываете ее как последовательность, вы можете в основном повторять ее (многократно) и все. 1008 *

4 голосов
/ 13 апреля 2010

Я думаю, что путаница может возникнуть из-за того, что коллекции типа List<T> реализуют интерфейс IEnumerable<T>. Если у вас есть отношение подтипа в целом (например, супертип Shape с двумя подтипами Rectangle и Circle), вы можете интерпретировать отношение как иерархию "is-a".

Это означает, что совершенно нормально говорить, что "Circle - это Shape", и аналогично, люди говорят, что "List<T> - это IEnumerable<T> "то есть" список является последовательностью". Это имеет некоторый смысл, потому что список - это особый тип последовательности. В общем, последовательности могут быть также лениво сгенерированы и бесконечны (и эти типы также не могут быть списками). Пример (совершенно корректной) последовательности, которая не может быть сгенерирована списком, будет выглядеть следующим образом:

// C# version                           // F# version
IEnumerable<int> Numbers() {            let rec loop n = seq {
  int i = 0;                               yield n
  while (true) yield return i++;           yield! loop(n + 1) }
}                                       let numbers = loop(0)

Это также было бы верно для F #, потому что тип F # list также реализует IEnumerable<T>, но функциональное программирование не делает такого сильного акцента на объектно-ориентированной точке зрения (и неявных преобразованиях, которые позволяют «является» интерпретация используется реже в F #).

2 голосов
/ 14 апреля 2010

Содержание последовательности рассчитывается по запросу, поэтому вы можете реализовать, например, бесконечную последовательность, не влияя на вашу память. Таким образом, в C # вы можете написать последовательность, например

IEnumerable<int> Null() {
  yield return 0;
}

Возвращает бесконечную последовательность нулей. Вы можете написать

int[] array = Null().Take(10).ToArray()

И это займет 10 * 4 байта памяти, несмотря на то, что последовательность бесконечна. Итак, как вы видите, в C # есть различие между последовательностью и коллекцией

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...