title: Create an object using Expression Trees without generic arguments
body: <p>I have a class that is a bit like the following</p>
  
  <pre><code>public class SpecialList&lt;T&gt; : List&lt;T&gt;
  {
      public SingleOrList() { }
      public SingleOrList(IEnumerable&lt;T&gt; list) : base(list) {}
      ...
  }
  </code></pre>
  
  <p>When converting it from JSON, it can be turned into this special list as either a single object, or an array of that object in the following manner.</p>
  
  <pre class="lang-cs prettyprint-override"><code>...
  
  public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  {
      var token = JToken.Load(reader);
  
      if (token.Type == JTokenType.Array)
      {
          var originalList = token.ToObject(objectType.BaseType, serializer);
          return Activator.CreateInstance(objectType, originalList);
      }
  
      var list = (IList) Activator.CreateInstance(objectType);
      var genericType = objectType.GetGenericArguments().Single();
      var single = token.ToObject(genericType, serializer);
  
      list.Add(single);
  
      return list;
  }
  </code></pre>
  
  <p>Ignoring the fact of whether or not this is a good idea for the moment, I was interested in whether you could use / how you would use complied expression trees here instead of <code>Activator.CreateInstance</code> to create the classes.</p>
  
  <p>Most of the examples I've seen use generics which is not possible for me here as I don't know up front the generic type, e.g.</p>
  
  <pre><code>public static Func&lt;T&gt; Instance = Expression.Lambda&lt;Func&lt;T&gt;&gt;(Expression.New(typeof(T))).Compile();
  </code></pre>
  
  <hr>
  
  <p>Based on canton7's comment, where <code>TypeCreators</code> is some form of cache:</p>
  
  <pre><code>private static IList CreateForType(Type objectType)
  {
      if (TypeCreators.TryGetValue(objectType, out var func))
      {
          return func();
      }
  
      var newFunc = Expression.Lambda&lt;Func&lt;IList&gt;&gt;(Expression.New(objectType)).Compile();
      TypeCreators.TryAdd(objectType, newFunc);
      return newFunc();
  }
  </code></pre>