title: What is the "type" of a generic IList<T>?
body: <p>Imagine an extension like this..</p>
  <pre><code>public static Blah&lt;T&gt;(this IList&lt;T&gt; ra)
   {
   ..
   }
  </code></pre>
  <p>Imagine you want to make a note of the most recently-called one.</p>
  <pre><code>private static IList recent;
  public static Blah&lt;T&gt;(this IList&lt;T&gt; ra)
   {
   recent = ra;
   ..
   }
  </code></pre>
  <p>You actually can not do that:</p>
  <blockquote>
  <p>error CS0266: Cannot implicitly convert type <code>System.Collections.Generic.IList&lt;T&gt;</code> to <code>System.Collections.IList</code>.</p>
  </blockquote>
  <p>1- You can simply make <code>recent</code> an <code>object</code> and that seems to work fine, but it seems like a poor solution.</p>
  <p>2- It seems if you do have recent as an <code>IList</code>, you can actually cast the &quot;ra&quot; to that...</p>
  <pre><code>recent = (System.Collections.IList)ra;
  </code></pre>
  <p>and it seems to work. Seems strange though??  So,</p>
  <p>3- Actually, <strong>what type should recent <em>be</em></strong> so that you don't have to cast to it?? How can you make <code>recent</code> the same type as <code>ra</code>? You can't say this ....</p>
  <pre><code>private static System.Collections.Generic.IList recent;
  </code></pre>
  <p>it's not meaningful.  So what the heck is the type of &quot;ra&quot;?  What should <code>recent</code> &quot;be&quot; so that you can simply say <code>recent=ra</code> ?</p>
  <p>(I mention this is for Unity, since you constantly use generic extensions in Unity.)</p>
  <hr />
  <p>4- Consider a a further difficulty the case if you want to have a Dictionary of them all.</p>
  <pre><code>private static Dictionary&lt;object,int&gt; recents = new Dictionary&lt;object,int&gt;();
  </code></pre>
  <p>I can really only see how to do it as an object.</p>
  <hr />
  <h1>USE CASE EXAMPLE.</h1>
  <p>Here's an extension you use constantly, everywhere, in game engineering,</p>
  <pre><code>public static T AnyOne&lt;T&gt;(this IList&lt;T&gt; ra)
      {
      int k = ra.Count;
      if (k&lt;=0) {Debug.Log(&quot;Warn!&quot;+k);}
      int r = UnityEngine.Random.Range(0,k);
      return ra[r];
      }
  </code></pre>
  <p>no problem so far. So,</p>
  <pre><code>explosions.AnyOne();
  yetAnotherEnemyToDefeat = dinosaurStyles.AnyOne();
  </code></pre>
  <p>and so on.  However.  Of course, actual random selections feel bad; in practice what you want is a <em>fairly non-repeating order, more like a shuffle</em>. Usually the best thing to do with any list or array is shuffle them, and serve them in that order; perhaps shuffle again each time through.  Simple example, you have 20 random sound effects <code>roars</code> , being for when the dino roars.  Each time you need one, if you do this</p>
  <pre><code> roars.AnyOne();
  </code></pre>
  <p>its OK, but not great. It will sound sort of suck.  (Most players will report it as &quot;not being random&quot; or &quot;repeating a lot&quot;.) This</p>
  <pre><code> roars.NextOne();
  </code></pre>
  <p>is much better.  So, <code>NextOne()</code> should, on its own, (a) if we're at the start shuffle the list, (b) serve it in that order, (c) perhaps shuffle it again each time you use up the list.  {There are further subtleties, eg, try not to repeat any near the end/start of the reshuffle, but irrelevant here.}</p>
  <p>Note that subclassing List (and/or array) would suck for many obvious reasons, it's a job for a simple self-contained extension.</p>
  <p>So then, here's a beautiful way to implement <code>NextOne()</code> using a simple stateful extension.</p>
  <pre><code>private static Dictionary&lt;object,int&gt; nextOne = new Dictionary&lt;object,int&gt;();
  public static T NextOne&lt;T&gt;(this IList&lt;T&gt; ra)
      {
      if ( ! nextOne.ContainsKey(ra) )
          // i.e., we've never heard about this &quot;ra&quot; before
          nextOne.Add(ra,0);
      
      int index = nextOne[ra];
      
      // time to shuffle?
      if (index==0)
          {
          Debug.Log(&quot;shuffling!&quot;); // be careful to mutate, don't change the ra!
          IList&lt;T&gt; temp = ra.OrderBy(r =&gt; UnityEngine.Random.value).ToList();
          ra.Clear(); foreach(T t in temp) ra.Add(t);
          }
      
      T result = ra[index];
      ++index;
      index=index%ra.Count;
      nextOne[ra] = index;
      return result;
      }
  </code></pre>
  <p>This is surely the perfect example of a &quot;stateful extension&quot;.</p>
  <p>Notice indeed, I just used &quot;object&quot;.</p>
  <p>I guess in a way, the fundamental question in this QA is, <strong>is it best to use the Dictionary of &quot;object&quot; there, or, would something else more typey be better?</strong>  Really that's the question at hand. Cheers!</p>