title: What is the difference between returning an Array and an IList<>? (RE: Eric Lippert's harmful arrays)
body: <p>I just read <a href="https://docs.microsoft.com/en-us/archive/blogs/ericlippert/arrays-considered-somewhat-harmful" rel="nofollow noreferrer">Eric Lippert's &quot;<em>Arrays considered somewhat harmful</em>&quot;</a> article.  He tells his readers that they &quot;probably should not return an array as the value of a public method or property,&quot; with the following reasoning (slightly paraphrased):</p>
  <blockquote>
  <p>Now the caller can take that array and replace the contents of it with whatever they please. The sensible thing to return is <code>IList&lt;&gt;</code>. You can build yourself a nice read-only collection object once, and then just pass out references to it as much as you want.</p>
  </blockquote>
  <p>In essence,</p>
  <blockquote>
  <p>An array is a collection of variables. The caller doesn’t want variables, but it’ll take them if that’s the only way to get the values. But neither the callee nor the caller wants those variables to ever vary.</p>
  </blockquote>
  <p>In an attempt to understand what he meant by variables vs. values, I built demo class that has <code>Array</code> and <code>IList&lt;&gt;</code> fields, and methods that return references to both.  <a href="http://csharppad.com/gist/cae586b881f74894e049" rel="nofollow noreferrer">Here it is on C# Pad.</a></p>
  <pre><code>class A {
      
      private readonly int[] arr = new []
      {
          10, 20, 30, 40, 50    
      };
      
      private readonly List&lt;int&gt; list = new List&lt;int&gt;(new []
      {
          10, 20, 30, 40, 50
      });
      
      public int[] GetArr()
      {
          return arr;
      }
      
      public IList&lt;int&gt; GetList()
      {
          return list;
      }
  }
  </code></pre>
  <p>If I understand correctly, the <code>GetArr()</code> method is Lippert's bad practice, and <code>GetList()</code> is his sensible practice.  Here is a demo of the bad caller mutability behavior of <code>GetArr()</code>:</p>
  <pre><code>var a = new A();
  var arr1 = a.GetArr();
  var arr2 = a.GetArr();
  
  Console.WriteLine(&quot;arr1[2]: &quot; + arr1[2].ToString());  // &gt; arr1[2]: 30
  Console.WriteLine(&quot;arr2[2]: &quot; + arr2[2].ToString());  // &gt; arr2[2]: 30
  
  // ONE CALLER MUTATES
  arr1[2] = 99;
  
  // BOTH CALLERS AFFECTED
  Console.WriteLine(&quot;arr1[2]: &quot; + arr1[2].ToString());  // &gt; arr1[2]: 99
  Console.WriteLine(&quot;arr2[2]: &quot; + arr2[2].ToString());  // &gt; arr2[2]: 99
  </code></pre>
  <p>But I don't understand his distinction - <strong>the <code>IList&lt;&gt;</code> reference has the same caller mutation problem:</strong></p>
  <pre><code>var a = new A();
  var list1 = a.GetList();
  var list2 = a.GetList();
  
  Console.WriteLine(&quot;list1[2]: &quot; + list1[2].ToString());  // &gt; list1[2]: 30
  Console.WriteLine(&quot;list2[2]: &quot; + list2[2].ToString());  // &gt; list2[2]: 30
  
  // ONE CALLER MUTATES
  list1[2] = 99;
  
  // BOTH CALLERS AFFECTED
  Console.WriteLine(&quot;list1[2]: &quot; + list1[2].ToString());  // &gt; list1[2]: 99
  Console.WriteLine(&quot;list2[2]: &quot; + list2[2].ToString());  // &gt; list2[2]: 99
  </code></pre>
  <p>Obviously, <strong><em>I trust that Eric Lippert knows what he's talking about</em>, so where have I misinterpreted him?  In what way is a returned <code>IList&lt;&gt;</code> reference safer than an <code>Array</code> reference?</strong></p>