Копировать значения ключа из 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 содержит строки и значения String, поэтому я просто хочу предоставить здесь метод, позволяющий копировать их в словарь generic.
Ответы
Ответ 1
Здесь нет смысла использовать дженерики, так как вы не можете назначить 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;
}
Ответ 2
Метод расширения плюс linq:
public static Dictionary<string, string> ToDictionary(this NameValueCollection nvc) {
return nvc.AllKeys.ToDictionary(k => k, k => nvc[k]);
}
//example
var dictionary = nvc.ToDictionary();
Ответ 3
parameters.AllKeys.ToDictionary(t => t, t => parameters[t]);
Ответ 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();
Ответ 5
Если вы знаете, что ваш словарь всегда будет содержать строки, укажите его, чтобы он содержал строки вместо создания вашего класса:
IDictionary<string, string> dict = new Dictionary<string, string>();
С этим все будет "работать", как написано (без спецификации общего метода).
Если вам нужно, чтобы это был общий класс и содержал общие данные, вам нужно каким-то образом преобразовать из string
в TKey
и string
в 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]));
}
}
Затем вам нужно будет передать делегат, в котором будет выполняться преобразование из строки в TValue
и строку в TKey
.
Ответ 6
Супер-короткая версия
var dataNvc = HttpUtility.ParseQueryString(data);
var dataCollection = dataNvc.AllKeys.ToDictionary(o => o, o => dataNvc[o]);
Ответ 7
Вы не должны забывать о 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;
}