title: IList<T> and IReadOnlyList<T>
body: <p>If I have a method that requires a parameter that,</p>
  
  <ul>
  <li>Has a <code>Count</code> property</li>
  <li>Has an integer indexer (get-only)</li>
  </ul>
  
  <p>What should the type of this parameter be? I would choose <code>IList&lt;T&gt;</code> before .NET 4.5 since there was no other indexable collection interface for this and arrays implement it, which is a big plus.</p>
  
  <p>But .NET 4.5 introduces the new <code>IReadOnlyList&lt;T&gt;</code> interface and I want my method to support that, too. How can I write this method to support both <code>IList&lt;T&gt;</code> and <code>IReadOnlyList&lt;T&gt;</code> without violating the basic principles like DRY?</p>
  
  <p><strong>Edit</strong>: Daniel's answer gave me some ideas:</p>
  
  <pre><code>public void Foo&lt;T&gt;(IList&lt;T&gt; list)
      =&gt; Foo(list, list.Count, (c, i) =&gt; c[i]);
  
  public void Foo&lt;T&gt;(IReadOnlyList&lt;T&gt; list)
      =&gt; Foo(list, list.Count, (c, i) =&gt; c[i]);
  
  private void Foo&lt;TList, TItem&gt;(
      TList list, int count, Func&lt;TList, int, TItem&gt; indexer)
      where TList : IEnumerable&lt;TItem&gt;
  {
      // Stuff
  }
  </code></pre>
  
  <hr>
  
  <p><strong>Edit 2:</strong> Or I could just accept an <code>IReadOnlyList&lt;T&gt;</code> and provide a helper like this:</p>
  
  <pre><code>public static class CollectionEx
  {
      public static IReadOnlyList&lt;T&gt; AsReadOnly&lt;T&gt;(this IList&lt;T&gt; list)
      {
          if (list == null)
              throw new ArgumentNullException(nameof(list));
  
          return list as IReadOnlyList&lt;T&gt; ?? new ReadOnlyWrapper&lt;T&gt;(list);
      }
  
      private sealed class ReadOnlyWrapper&lt;T&gt; : IReadOnlyList&lt;T&gt;
      {
          private readonly IList&lt;T&gt; _list;
  
          public ReadOnlyWrapper(IList&lt;T&gt; list) =&gt; _list = list;
  
          public int Count =&gt; _list.Count;
  
          public T this[int index] =&gt; _list[index];
  
          public IEnumerator&lt;T&gt; GetEnumerator() =&gt; _list.GetEnumerator();
  
          IEnumerator IEnumerable.GetEnumerator() =&gt; GetEnumerator();
      }
  }
  </code></pre>
  
  <p>Then I could call it like <code>Foo(list.AsReadOnly())</code></p>
  
  <hr>
  
  <p><strong>Edit 3:</strong>  Arrays implement both <code>IList&lt;T&gt;</code> and <code>IReadOnlyList&lt;T&gt;</code>, so does the <code>List&lt;T&gt;</code> class. This makes it pretty rare to find a class that implements <code>IList&lt;T&gt;</code> but not <code>IReadOnlyList&lt;T&gt;</code>.</p>