title: Implementing a generic ToConcurrentDictionary extension method
body: <p>I Was trying to add some type safe dictionary logic to my app and tried to look around for an implementation to convert a given dictionary to a concurrent one. After searching for a while with no luck, I ended up implementing a version of my own with some hacked up code. below is the version I have come up with:</p>
  
  <pre><code>    public static class Extensions
        {
          public static ConcurrentDictionary&lt;TKey, TValueResult&gt; ToConcurrentDictionary&lt;TKey, TValueInput, TValueResult&gt;(this IEnumerable&lt;KeyValuePair&lt;TKey, TValueInput&gt;&gt; input)
          {
            var result = new ConcurrentDictionary&lt;TKey, TValueResult&gt;();
            foreach (var kv in input)
            {
              if (typeof(TValueInput).IsDictionaryType())
              {
                var mi = MethodInfo.GetCurrentMethod() as MethodInfo;
                var valGenericArgs = typeof(TValueInput).GetGenericArguments();
                if (valGenericArgs.Length &gt; 0 &amp;&amp; valGenericArgs.Last().IsDictionaryType())
                {
                  Type generic = typeof(ConcurrentDictionary&lt;,&gt;);
                  var conDicType = generic.MakeGenericType(typeof(TValueResult).GetGenericArguments().Last().GetGenericArguments());
                  valGenericArgs = valGenericArgs.Concat(new Type[] { conDicType }).ToArray();
                }
                else
                {
                  valGenericArgs = valGenericArgs.Concat(new Type[] { valGenericArgs.Last() }).ToArray();
                }
                var genMi = mi.MakeGenericMethod(valGenericArgs);
                var newDic = genMi.Invoke(null, new object[] { kv.Value });
                result.TryAdd(kv.Key, (TValueResult)newDic);
              }
              else
              {
                result.TryAdd(kv.Key, (TValueResult)Convert.ChangeType(kv.Value, typeof(TValueResult)));
              }
            }
            return result;
          }
  
          public static bool IsDictionaryType(this Type type)
          {
            return type.FullName.StartsWith("System.Collections.Generic.IDictionary`")
              || type.GetInterfaces().Any(t =&gt; t.FullName.StartsWith("System.Collections.Generic.IDictionary`"));
          }
  }
  </code></pre>
  
  <p>Using the method is like below:</p>
  
  <pre><code>  var dic1 = new Dictionary&lt;string, Dictionary&lt;int, IDictionary&lt;string, int&gt;&gt;&gt; 
      { 
          {"one", new Dictionary&lt;int, IDictionary&lt;string, int&gt;&gt;
                  {
                      {11, new Dictionary&lt;string,int&gt;
                                  {
                                      {"one-one-one", 10000}
                                  }
                      }
                  }
          }
      };
    var dic2 = new Dictionary&lt;int, IDictionary&lt;int, IDictionary&lt;int, string&gt;&gt;&gt; 
      { 
          {1, new Dictionary&lt;int, IDictionary&lt;int, string&gt;&gt;
                  {
                      {11, new Dictionary&lt;int,string&gt;
                                  {
                                      {111, "one-one-one"}
                                  }
                      }
                  }
          }
      };
  
    var dic3 = new Dictionary&lt;int, string&gt; 
                                  {
                                      {111, "one-one-one"}
                                  };
  
    var cd1 = dic1.ToConcurrentDictionary&lt;string, Dictionary&lt;int, IDictionary&lt;string, int&gt;&gt;, ConcurrentDictionary&lt;int, ConcurrentDictionary&lt;string, int&gt;&gt;&gt;();
    var cd2 = dic2.ToConcurrentDictionary&lt;int, IDictionary&lt;int, IDictionary&lt;int, string&gt;&gt;, ConcurrentDictionary&lt;int, ConcurrentDictionary&lt;int, string&gt;&gt;&gt;();
    var cd3 = dic3.ToConcurrentDictionary&lt;int, string, string&gt;();
  </code></pre>
  
  <p>Any suggestions to improve this method or any better alternatives to achieve the same results? </p>