Alternative to IEnumerable for read-only collections

.NET 4.5 introduced a new interface which is great if you want to expose a collection as readonly.

The problem with IEnumerable<T> is that it’s forward only. i.e. there is no guarantee that you can traverse it multiple times. The collection size might also be unknown, depending on the implementation.

So if you want to expose a collection which can be traversed multiple times and where the size is know there is as of .NET 4.5 another alternative. And that’s IReadOnlyList<T>. It inherits another new interface called IReadOnlyCollection<out T>.

Code

public interface IReadOnlyCollection<out T> 
      : IEnumerable<T>, 
        IEnumerable
{
    int Count { get; }
}
public interface IReadOnlyList<out T> 
      : IReadOnlyCollection<T>
      , IEnumerable<T>
      , IEnumerable
{
    T this[int index] { get; }
}

Usage example

public class MyRepository
{
    public IReadOnlyList<User> FindUsers(string lastName)
    {
        // [...]
    }

    // [...]
}

  • willy_duit

    You can traverse IEnumerable multiple times. It’s IEnumerator that you can’t.

    • sehrgut

      That’s actually incorrect. While the IEnumerable interface does not actively prevent multiple traversal, it also doesn’t promise it. The IEnumerable may have a forward-only data source (like a stream or a DataReader) behind it, and if the concrete type is such, it will simply throw an exception when the second traversal is attempted.

      If you control all code manipulating your IEnumerable (i.e. it’s private, and all the code that populates and consumes it is private), you can safely guarantee that the concrete type is multiply-traversable. It’ll still throw a compiler warning, but it won’t messily die.

      Assuming someone else’s IEnumerable is multiply-traversable is a recipe for delayed disaster and subtle bugs when third-party library updates are installed.