38

尝试将值从现有 NameValueCollection 对象复制到字典。我有下面的代码可以做到这一点,但似乎 Add 不接受我的键和值是字符串

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 包含字符串键和值,所以我只想在这里提供一种方法,允许将它们复制到通用字典。

4

7 回答 7

76

扩展方法加linq:

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

 //example
 var dictionary = nvc.ToDictionary();
于 2013-12-18T23:20:23.780 回答
37

在这里使用泛型是没有意义的,因为你不能将strings 分配给一些任意的泛型类型:

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;
}
于 2013-05-14T18:01:23.453 回答
23
parameters.AllKeys.ToDictionary(t => t, t => parameters[t]);
于 2014-10-10T04:50:32.653 回答
5

使用 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();
于 2013-05-14T18:08:02.823 回答
3

超短版

var dataNvc = HttpUtility.ParseQueryString(data);
var dataCollection = dataNvc.AllKeys.ToDictionary(o => o, o => dataNvc[o]);
于 2014-06-05T07:22:48.467 回答
2

如果您知道您的字典总是包含字符串,请将其指定为包含字符串,而不是使您的类通用:

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

有了这个,事情就会像写的那样“正常工作”(没有通用方法规范)。

如果您需要它成为一个泛型类并保存泛型数据,您需要某种方式来转换 from stringtoTKeystringto TValue。您可以为您的复制方法提供委托来执行此操作:

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]));
    }
}

然后,您需要传递一个委托,该委托将执行从 string toTValue和 string to的转换TKey

于 2013-05-14T18:01:44.293 回答
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;
  }
于 2016-07-12T08:43:00.323 回答