title: What's the best pattern for passing Immutable Collections across APIs
body: <p>Before immutability, <strong>IEnumerable</strong> was the go-to interface in many APIs since this had the advantage that the API was insensitive to the actual type of the passed object.</p>
  
  <pre><code>public void DoSomeEnumerationsWithACollection(IEnumerable&lt;Thing&gt; collectionOfThings)
  { 
     foreach (var thing in collectionOfThings) doSomethingWith(thing);
     foreach (var thing in collectionOfThings) doSomethingElseWith(thing);
  }
  </code></pre>
  
  <p>Of course there are at least two downsides to this:</p>
  
  <ol>
  <li><p>The code behind the API can't rely on the immutability of <strong>collectionOfThings</strong> and may encounter a  "collection modified" exception or hit other other subtle issues.</p></li>
  <li><p>We don't know whether <strong>collectionOfThings</strong> is real collection or simply a deferred query.  If we assume it's a real collection and it isn't we run the risk of degrading performance by running multiple  enumerations.  If we assume it's a deferred query and it's actually a real collection then turning it into a local  list or other frozen collection incurs unnecessary cost although it does help protect us against the first problem (there's still a race condition whilst performing  the "ToList" operation).  Obviously we can write a small amount of code to check for this and try to do the "right thing" but this is  annoying  extra clutter.  </p></li>
  </ol>
  
  <p>I must admit I have never found a satisfactory pattern to address this other than using naming conventions.  The pragmatic approach seemed to be that <strong>IEnumerable</strong> was the lowest friction approach for passing around collections, despite the downsides.</p>
  
  <p>Now, with immutable collections, the situation is much improved...</p>
  
  <pre><code>public void DoSomeEnumerationsWithACollection(ImmutableList&lt;Thing&gt; collectionOfThings)
  { 
  </code></pre>
  
  <p>There is no longer a risk of collection modification and there's no ambiguity about the performance impact of multiple enumerations.</p>
  
  <p>However, we have apparently lost flexibility on the API since we now have to pass in an <strong>ImmutableList</strong>.  If our client had some other kind of enumerable immutable collection, it would have to be copied into an <strong>ImmutableList</strong> in order to be consumed even though all we want to do is enumerate it.</p>
  
  <p>Ideally we'd be able to use an interface like </p>
  
  <pre><code>public void DoSomeEnumerationsWithACollection(IImmutableEnumerable&lt;Thing&gt; collectionOfThings)
  </code></pre>
  
  <p>but of course, an interface can't enforce semantics like immutability except by convention.</p>
  
  <p>Using a base class might work </p>
  
  <pre><code>public void DoSomeEnumerationsWithACollection(ImmutableEnumerableBase&lt;Thing&gt; collectionOfThings)
  </code></pre>
  
  <p>except that it's considered bad form to create unsealed immutable classes lest a subclass introduce mutability.  And in any case, this hasn't been done in the BCL.</p>
  
  <p>Or we could just keep using IEnumerable in the API and using a naming convention to make it clear our code relies upon an immutable collection to be passed in.  </p>
  
  <p><em>So... my question is what patterns are considered best when passing around immutable collections?  Is <strong>ImmutableList</strong> the "new <strong>IEnumerable</strong>" once we start using immutablity or is there a better way?</em></p>
  
  <p><em>Update</em></p>
  
  <p><strong>IReadOnlyCollection</strong> (suggested by Yuval Itzchakov below ) is a distinct improvement over <strong>IEnumerable</strong> but still does not fully protect the consumer against uncontrolled changes in the collection.  It's notable that the Roslyn codebase makes heavy use of immutability (mainly via <strong>ImmutableArray</strong>) and appears to use explicit typing when passing these into other methods though there are a couple of locations where <strong>ImmutableList</strong>s are passed into methods that accept <strong>IEnumerable</strong>.</p>