Enhanced C#
Language of your choice: library documentation
Public Member Functions | List of all members
Loyc.Collections.IListSource< out out T > Interface Template Reference

A read-only list indexed by an integer. More...

Source file:
Inheritance diagram for Loyc.Collections.IListSource< out out T >:
Loyc.Collections.ITryGet< int, T > Loyc.Collections.IIndexed< int, T >


A read-only list indexed by an integer.

Member list:

public IEnumerator<T> GetEnumerator(); // inherited
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(); // inherited
public T this[int index] { get; } // inherited
public int Count { get; } // inherited
public T TryGet(int index, out bool fail); // inherited
IRange<T> Slice(int start, int count = int.MaxValue);

The term "source" means a read-only collection, as opposed to a "sink" which is a write-only collection.

IListSource was created before .NET's IReadOnlyList but was later retrofitted so that IListSource implements IReadOnlyList. In addition, IListSource supports slices through its Slice() method, and it has TryGet methods to eliminate the need to call Count before reading from the list.

I have often wanted to access the "next" or "previous" item in a list, e.g. during parsing, but it inconvenient if you have to worry about whether the the current item is the first or last. In that case you must check whether the array index is valid, which is both inconvenient and wasteful, because the list class itself will check the array index a second time, and then the .NET runtime will check the index a third time when reading the internal array. The TryGet(index, defaultValue) extension method can be used to return a default value if the index is not valid, using only one interface call.

Design footnote: Ideally the return type of TryGet would be Maybe<T>, but that design would not allow T to be covariant (out T). Therefore, the version of TryGet that returns Maybe<T> is an extension method.

Using Impl.ListSourceBase<T> as your base class can help you implement this interface more quickly.

Public Member Functions

IRange< T > Slice (int start, int count=int.MaxValue)
 Returns a sub-range of this list. More...
- Public Member Functions inherited from Loyc.Collections.ITryGet< int, T >
TryGet (K key, out bool fail)
 Gets the item for the specified key or index, and does not throw an exception on failure. More...

Additional Inherited Members

- Properties inherited from Loyc.Collections.IIndexed< int, T >
this[K key] [get]
 Gets the value associated with the specified key. More...

Member Function Documentation

◆ Slice()

IRange<T> Loyc.Collections.IListSource< out out T >.Slice ( int  start,
int  count = int.MaxValue 

Returns a sub-range of this list.

startThe new range will start at this index in the current list (this location will be index [0] in the new range).
countThe desired number of elements in the new range, or int.MaxValue to get all elements until the end of the list.
Returns a sub-range of this range.
ArgumentExceptionThe start index was below zero.

The (start, count) range is allowed to be invalid, as long as start is zero or above.

  • If count is below zero, or if start is above the original Count, the Count of the new slice is set to zero.
  • if (start + count) is above the original Count, the Count of the new slice is reduced to this.Count - start. Implementation note: do not compute (start + count) because it may overflow. Instead, test whether (count > this.Count - start).

Most collections should use the following implementation:

IRange<T> IListSource<T>.Slice(int start, int count) { return Slice(start, count); }
public Slice_<T> Slice(int start, int count) { return new Slice_<T>(this, start, count); }

Referenced by Loyc.Collections.NegListSource< T >.Slice().

Loyc.Collections.ITryGet< int, T >::TryGet
V TryGet(K key, out bool fail)
Gets the item for the specified key or index, and does not throw an exception on failure.
IRange< T > Slice(int start, int count=int.MaxValue)
Returns a sub-range of this list.