Osy#betaRun it on Osyrin: osyrin.com

Reference / Types

IEnumerable<T>, IReadOnlyList<T>, IList<T> — the collection interfaces

IEnumerable<T> · IReadOnlyList<T> · IReadOnlyCollection<T> → T[] · IList<T> · ICollection<T> → List<T>

C#'s collection interfaces are accepted wherever a type is written, each as the collection it names: IEnumerable<T>, IReadOnlyList<T> and IReadOnlyCollection<T> are a read-only sequence (T[]), IList<T> and ICollection<T> a List<T>, ISet<T> a HashSet<T>, IDictionary<K, V> a Dictionary<K, V>. A List<T> passes where a read-only sequence is asked for.

stable1 example compiled by CItypescollectionscsharp

Summary#

Write the interface C# code writes; it means the collection it names:

int Total(IEnumerable<int> xs) {
  int t = 0;
  foreach (var x in xs) { t += x; }
  return t;
}

void AddTo(IList<string> names, string name) { names.Add(name); }

IEnumerable<int> Evens(List<int> xs) => xs.Where(x => x % 2 == 0);

[Test]
void Interfaces_Are_The_Collections_They_Name() {
  Assert.Equal(3, Total(new List<int> { 1, 2 }));     // a List passes for a read-only sequence
  var names = new List<string>();
  AddTo(names, "Ada");
  Assert.Equal(1, names.Count);
  IReadOnlyList<int> evens = Evens(new List<int> { 1, 2, 3, 4 }).ToList();
  Assert.Equal(2, evens.Count());
}

Signature#

IEnumerable<T> / IReadOnlyList<T> / IReadOnlyCollection<T>   // the read-only sequence: T[]
IList<T> / ICollection<T>                                     // List<T>
ISet<T> / IReadOnlySet<T>                                     // HashSet<T>
IDictionary<K, V> / IReadOnlyDictionary<K, V>                 // Dictionary<K, V>

Description#

What is the difference from C#?#

Osy# has no interface OVER its collections, so each interface is exactly one collection rather than a promise any collection can keep. The read-only ones are the array, which is read-only by construction; the mutable ones are the list. A value of the other kind converts where C# would accept it — a List<T> passes for an IEnumerable<T>.

IQueryable<T> is different: it is a QUERY over stored rows, not a collection in hand (Query<T>).

See also#

Related

IEnumerable<T> with yield return — iterators

A function declared `IEnumerable<T>` whose body uses `yield return` is a C# iterator: each `yield return` adds one item…

Query<T>

Holds a query instead of its rows. A clause you write against a `Query<T>` joins the query rather than filtering rows…

Sequence fields on a class

A class can hold many values in one field — `string[]`, `int[]`, `List<Tag>`, `HashSet<string>`, `Dictionary<string…