2014-02-19 2 views
1

저는 형식이 안전한 사전 논리를 응용 프로그램에 추가하려고 시도했으며 특정 사전을 동시 사전으로 변환하는 구현을 둘러 보려고했습니다. 운이없는 잠시 동안 검색을 마친 후에 해킹 된 코드로 내 버전을 구현하게되었습니다. 아래의 버전은 내가 함께 올라와있다되어 동일한 결과를 달성하기 위해이 방법 또는 더 나은 대안을 개선하기 위해일반 ToConcurrentDictionary 확장 메서드 구현

var dic1 = new Dictionary<string, Dictionary<int, IDictionary<string, int>>> 
    { 
     {"one", new Dictionary<int, IDictionary<string, int>> 
       { 
        {11, new Dictionary<string,int> 
           { 
            {"one-one-one", 10000} 
           } 
        } 
       } 
     } 
    }; 
    var dic2 = new Dictionary<int, IDictionary<int, IDictionary<int, string>>> 
    { 
     {1, new Dictionary<int, IDictionary<int, string>> 
       { 
        {11, new Dictionary<int,string> 
           { 
            {111, "one-one-one"} 
           } 
        } 
       } 
     } 
    }; 

    var dic3 = new Dictionary<int, string> 
           { 
            {111, "one-one-one"} 
           }; 

    var cd1 = dic1.ToConcurrentDictionary<string, Dictionary<int, IDictionary<string, int>>, ConcurrentDictionary<int, ConcurrentDictionary<string, int>>>(); 
    var cd2 = dic2.ToConcurrentDictionary<int, IDictionary<int, IDictionary<int, string>>, ConcurrentDictionary<int, ConcurrentDictionary<int, string>>>(); 
    var cd3 = dic3.ToConcurrentDictionary<int, string, string>(); 

어떤 제안 : 방법을 사용하여

public static class Extensions 
     { 
     public static ConcurrentDictionary<TKey, TValueResult> ToConcurrentDictionary<TKey, TValueInput, TValueResult>(this IEnumerable<KeyValuePair<TKey, TValueInput>> input) 
     { 
      var result = new ConcurrentDictionary<TKey, TValueResult>(); 
      foreach (var kv in input) 
      { 
      if (typeof(TValueInput).IsDictionaryType()) 
      { 
       var mi = MethodInfo.GetCurrentMethod() as MethodInfo; 
       var valGenericArgs = typeof(TValueInput).GetGenericArguments(); 
       if (valGenericArgs.Length > 0 && valGenericArgs.Last().IsDictionaryType()) 
       { 
       Type generic = typeof(ConcurrentDictionary<,>); 
       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 => t.FullName.StartsWith("System.Collections.Generic.IDictionary`")); 
     } 
} 

은 다음과 같다?

+0

나는 이것이 C# 질문이라고 생각하십니까? – vemv

+0

예 @vemv. 이것을 지적 해 주셔서 감사합니다. – siva

답변

0

더 나은 대안이없는 것처럼 보입니다. 자신의 견해를 공유 한 모두에게 감사드립니다.

1

MSDN에서 보면 ConcurrentDictionary의 생성자가 있으며 KeyValuePairs의 IEnumerable을 사용할 수 있습니다. 이것이 당신이 원하는 것을 성취합니까?

public static ConcurrentDictionary<TKey, TValue> ToConcurrentDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> input) 
{ 
     return new ConcurrentDictionary<TKey, TValue>(input); 
} 
+0

예 제레미하지만 구현은 부분적으로 만 문제를 해결합니다. 하나의 레벨에서 작동하지만, 예를 들어 다른 사전이나 여러 레벨의 TValue를 가지고 있다면이 구현은 내부 사전을 동시 변환하는 것을 무시합니다. – siva

0
//Translate A to B 
var a = new Dictionary<Dictionary<string, string>>(); 
var b = a.SerializeJson() 
     .DeserializeJson<ConcurrentDictionary<ConcurrentDictionary<string,string>>();