2013-05-14 5 views
20

에 복사합니다. 기존 NameValueCollection 개체의 값을 사전에 복사하려고합니다. 나는 그렇게하려면 아래에 다음 코드를 가지고 있지만 추가 내 키와 값이 문자열로 것을 허용하지 않는 것 같다NameValueCollection의 키 값을 일반 사전

IDictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>(); 
public void copyFromNameValueCollection (NameValueCollection a) 
{ 
    foreach (var k in a.AllKeys) 
    { 
     dict.Add(k, a[k]); 
    } 
} 

참고 : NameValueCollection은 문자열의 키와 값을 포함하고 그래서 단순히 여기에 제공 할 메서드를 사용하여 일반 사전에 복사 할 수 있습니다.

+2

아마도 이것은 'TKey','TValue' 유형 매개 변수를 선언하는 제네릭 유형 * 및 * 메소드 *가 해당 유형 매개 변수를 선언하기 때문에 매우 혼란 스럽습니다. 거기에 키가 항상 문자열이된다는 사실을 추가하십시오 ... 그렇다면 TKey가 Guid 일 경우 어떻게 될 것으로 예상합니까? –

+0

함께 작업하려면 일반 사전이 필요합니다. NameValueCollection 객체에서 키와 값을 복사 할 수있는 serialize 가능한 사전 클래스를 작성하는 것임을 참고하십시오. – Kobojunkie

+1

TKey가 문자열이 아닌 경우 다시 무엇을할까요? –

답변

26

그것은 당신이 어떤 임의의 제네릭 형식에 string의를 할당 할 수 있기 때문에 여기에 제네릭을 사용하는 것이 이해가되지 않습니다 :

IDictionary<string, string> dict = new Dictionary<string, string>(); 

public void copyFrom(NameValueCollection a) 
{ 
      foreach (var k in a.AllKeys) 
      { 
       dict.Add(k, a[k]); 
      } 
} 

당신은 아마 대신 새 사전을 만들 수있는 방법을 만들어야합니다 있지만 :

public static IDictionary<string, string> ToDictionary(this NameValueCollection col) 
{ 
    IDictionary<string, string> dict = new Dictionary<string, string>(); 
    foreach (var k in col.AllKeys) 
    { 
     dict.Add(k, col[k]); 
    } 
    return dict; 
} 

당신처럼 사용할 수있는 :

NameValueCollection nvc = // 
var dictionary = nvc.ToDictionary(); 

하는 경우 당신이 당신의 사전이 항상 문자열을 포함하는 것이라는 것을 알고 있다면 포함을 지정

public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(this NameValueCollection col) 
{ 
    var dict = new Dictionary<TKey, TValue>(); 
    var keyConverter = TypeDescriptor.GetConverter(typeof(TKey)); 
    var valueConverter = TypeDescriptor.GetConverter(typeof(TValue)); 

    foreach(string name in col) 
    { 
     TKey key = (TKey)keyConverter.ConvertFromString(name); 
     TValue value = (TValue)valueConverter.ConvertFromString(col[name]); 
     dict.Add(key, value); 
    } 

    return dict; 
} 
+0

NameValueCollection에는 문자열 키와 값이 있습니다. 나는 그들을 일반 사전에 복사 할 수 있기를 원합니다. – Kobojunkie

+0

@Kobojunkie - 키와 값 유형이 무엇이든 될 수 있기 때문에 일반 사전에 복사 할 수 없습니다. 'Dictionary '또는 덜 파생 된 키 또는 값 유형으로 만 복사 할 수 있습니다. '개체'. – Lee

+0

나는 그 말이 맞다고 생각하지 않습니다. – Kobojunkie

2

: 당신은 당신이 형식 변환기를 사용하여 필요한 키/값 형식으로 컬렉션의 문자열을 변환하는 일반적인 방법을 원하는 대신 클래스는 일반적인 만드는 문자열 : (일반 메소드 스펙없이) 작성된이와

IDictionary<string, string> dict = new Dictionary<string, string>(); 

는 상황이 "그냥 작동"합니다. 이 제네릭 클래스가 될 필요가 있고, 일반적인 데이터를 저장할 경우

, 당신은 TValueTKeystringstring 변환 할 수있는 방법이 필요합니다. 이 작업을 수행하기 위해 복사 방법에 대표단을 제공 할 수있다 : 즉 TKeyTValue와 문자열로 문자열에서 변환을 수행 할에 그런 다음 대리자를 통과해야

public void CopyFrom(NameValueCollection a, Func<string, TKey> keyConvert, Func<string, TValue> valueConvert) 
{ 
    foreach(var k in a.AllKeys) 
    { 
     dict.Add(keyConvert(k), valueConvert(a[k])); 
    } 
} 

.

+0

이 대답은'NameValueCollection's에 null 키가있을 수 있으며,이 불일치는 사전에 변환 할 때 반드시 고려해야한다는 점을 언급해야합니다.이 키는 null이 아닌 키가 없습니다. – smartcaveman

+0

사전에 항상 문자열이 들어있는 것은 아닙니다. 이 메소드에서 NameValueCollection 객체의 값을 복사 할 수도 있습니다. – Kobojunkie

+1

@Kobojunkie 그러면 두 번째 메커니즘이 필요합니다. 문자열에서 유형으로 변환해야합니다. –

4

사용 LINQ :

public static IDictionary<string, string> ToDictionary(this NameValueCollection collection) 
{ 
    return collection.Cast<string>().ToDictionary(k => k, v => collection[v]); 
} 

사용법 :

IDictionary<string, string> dic = nv.ToDictionary(); 
48

확장 방법 플러스 LINQ :

public static Dictionary<string, string> ToDictionary(this NameValueCollection nvc) { 
    return nvc.AllKeys.ToDictionary(k => k, k => nvc[k]); 
} 

//example 
var dictionary = nvc.ToDictionary(); 
1

슈퍼 짧은 버전

var dataNvc = HttpUtility.ParseQueryString(data); 
var dataCollection = dataNvc.AllKeys.ToDictionary(o => o, o => dataNvc[o]); 
12
parameters.AllKeys.ToDictionary(t => t, t => parameters[t]); 
0

당신은 EqualityComparer를 잊어서는 안됩니다. 그러나 그것은 공공 재산이 아닙니다. 그래서, 그것을 얻기 위해 반성을 사용해야합니다.

public static IEqualityComparer GetEqualityComparer(this NameObjectCollectionBase nameObjectCollection) 
    { 
    PropertyInfo propertyInfo = typeof(NameObjectCollectionBase).GetProperty("Comparer", BindingFlags.Instance | BindingFlags.NonPublic); 
    return (IEqualityComparer)propertyInfo.GetValue(nameObjectCollection); 
    } 

public static IEqualityComparer<string> GetEqualityComparer(this NameValueCollection nameValueCollection) 
    { 
    return (IEqualityComparer<string>)((NameObjectCollectionBase)nameValueCollection).GetEqualityComparer(); 
    } 

public static Dictionary<string, string> ToDictionary(this NameValueCollection nameValueCollection) 
    { 
    Dictionary<string, string> dictionary = 
    nameValueCollection.AllKeys.ToDictionary(x => x, x => nameValueCollection[x], nameValueCollection.GetEqualityComparer()); 
    return dictionary; 
    }