Я думаю, что путаница может возникнуть из-за того, что коллекции типа 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 #).