title: Creating an ImmutableList of a type that is unknown at compile-time
body: <p>Given a <code>Collection&lt;T&gt;</code> whose type <code>T</code> is only known in runtime (not at compile time), I would like to generate an <code>ImmutableList&lt;T&gt;</code>.</p>
  
  <p>The method I would like to create may like like:</p>
  
  <pre><code>var immutableList = CreateImmutableList(originalList, type);
  </code></pre>
  
  <p>where originalList is <code>IEnumerable</code> and type is the <code>T</code> of of the generated <code>ImmutableList&lt;T&gt;</code>.</p>
  
  <p>How?!</p>
  
  <p>(I'm working with NET .Core)</p>
  
  <p>EDIT: Thanks to the comments I have found a working solution. It uses AddRange method.</p>
  
  <pre><code>namespace Sample.Tests
  {
      using System;
      using System.Collections;
      using System.Collections.Immutable;
      using System.Collections.ObjectModel;
      using System.Linq;
      using System.Reflection;
      using Xunit;
  
      public class ImmutabilityTests
      {
          [Fact]
          public void CollectionCanBeConvertedToImmutable()
          {
              var original = new Collection&lt;object&gt;() { 1, 2, 3, 4, };
              var result = original.AsImmutable(typeof(int));
  
              Assert.NotEmpty(result);
              Assert.IsAssignableFrom&lt;ImmutableList&lt;int&gt;&gt;(result);
          }
      }
  
      public static class ReflectionExtensions
      {
          public static IEnumerable AsImmutable(this IEnumerable collection, Type elementType)
          {
              var immutableType = typeof(ImmutableList&lt;&gt;).MakeGenericType(elementType);
              var addRangeMethod = immutableType.GetMethod("AddRange");
              var typedCollection = ToTyped(collection, elementType);
  
              var emptyImmutableList = immutableType.GetField("Empty").GetValue(null);
              emptyImmutableList = addRangeMethod.Invoke(emptyImmutableList, new[] { typedCollection });
              return (IEnumerable)emptyImmutableList;
          }
  
          private static object ToTyped(IEnumerable original, Type type)
          {
              var method = typeof(Enumerable).GetMethod("Cast", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(type);
              return method.Invoke(original, new object[] { original });
          }
      }
  }
  </code></pre>