title: How to prevent a method caller from modifying a returned collection?
body: <p>I have methods returning private collections to the caller and I want to prevent the caller from modifying the returned collections.</p>
  
  <pre><code>private readonly Foo[] foos;
  
  public IEnumerable&lt;Foo&gt; GetFoos()
  {
      return this.foos;
  }
  </code></pre>
  
  <p>At the moment the private collection is a fixed array, but in the future the collection might become a list if the need for adding new items at run time arises.</p>
  
  <p>There are several solutions to prevent the caller from modifying the collection. Returning <code>IEnumerable&lt;T&gt;</code> is the simplest solution, but the caller can still up-cast the return value to <code>IList&lt;T&gt;</code> and modify the collection.</p>
  
  <pre><code>((IList&lt;Foo&gt;)GetFoos())[0] = otherFoo;
  </code></pre>
  
  <p>Cloning the collections has the obvious disadvantage that there are two collections that can evolve independently. So far I have considered the following options.</p>
  
  <ol>
  <li>Wrapping the collection in <code>ReadOnlyCollection&lt;T&gt;</code>.</li>
  <li>Returning one of the LINQ iterators defined by the <code>Enumerable</code> class by performing a dummy projection like <code>list.Select(item =&gt; item)</code>. Actually I consider using <code>Where(item =&gt; true)</code> because the returned iterator seems more lightweight.</li>
  <li>Writing a custom wrapper.</li>
  </ol>
  
  <p>What I don't like about using <code>ReadOnlyCollection&lt;T&gt;</code> is that it implements <code>IList&lt;T&gt;</code> and calling <code>Add()</code> or accessing the indexer will cause exceptions. While this is absolutly correct in theory, almost no real code checks <code>IList&lt;T&gt;.IsReadOnly</code> or <code>IList&lt;T&gt;.IsFixedSize</code>.</p>
  
  <p>Using the LINQ iterators - I wrapped the code in an extension method <code>MakeReadOnly()</code> - prevents this scenario, but it has the taste of a hack.</p>
  
  <p>Writing a custom wrapper? Reinventing the wheel?</p>
  
  <p>Any thoughts, considerations, or other solutions?</p>
  
  <hr>
  
  <p>While tagging this question, I discovered <a href="https://stackoverflow.com/questions/491375/readonlycollection-or-ienumerable-for-exposing-member-collections">this Stack Overflow question</a> I didn't notice before. Jon Skeet suggest to use the "LINQ hack", too, but even more efficient using <code>Skip(0)</code>.</p>