IList<T> and IReadOnlyList<T>

Posted by Safak Gür on Stack Overflow See other posts from Stack Overflow or by Safak Gür
Published on 2012-10-11T11:07:09Z Indexed on 2012/10/11 15:37 UTC
Read the original article Hit count: 172

Filed under:
|
|
|
|

My problem is that I have a method that can take a collection as parameter that,

  • Has a Count property
  • Has an integer indexer (get-only)

And I don't know what type should this parameter be. I would choose IList<T> before .NET 4.5 since there is no other indexable collection interface for this and arrays implement it, which is a big plus.

But .NET 4.5 introduces the new IReadOnlyList<T> interface and I want my method to support that, too. How can I write this method to support both IList<T> and IReadOnlyList<T> without violating the basic principles like DRY?

Can I convert IList<T> to IReadOnlyList<T> somehow in an overload?
What is the way to go here?

Edit: Daniel's answer gave me some pretty ideas, I guess I'll go with this:

public void Do<T>(IList<T> collection)
{
    DoInternal(collection, collection.Count, i => collection[i]);
}
public void Do<T>(IReadOnlyList<T> collection)
{
    DoInternal(collection, collection.Count, i => collection[i]);
}

private void DoInternal<T>(IEnumerable<T> collection,
    int count, Func<int, T> indexer)
{
    // Stuff
}

Or I could just accept a ReadOnlyList<T> and provide an helper like this:

public static class CollectionEx
{
    public static IReadOnlyList<T> AsReadOnly<T>(this IList<T> collection)
    {
        if (collection == null)
            throw new ArgumentNullException("collection");

        return new ReadOnlyWrapper<T>(collection);
    }

    private sealed class ReadOnlyWrapper<T> : IReadOnlyList<T>
    {
        private readonly IList<T> _Source;

        public int Count { get { return _Source.Count; } }
        public T this[int index] { get { return _Source[index]; } }

        public ReadOnlyWrapper(IList<T> source) { _Source = source; }

        public IEnumerator<T> GetEnumerator() { return _Source.GetEnumerator(); }
        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
    }
}

Then I could call Do(array.AsReadOnly())

© Stack Overflow or respective owner

Related posts about c#

Related posts about .NET