Essayer de copier les valeurs d'un objet NameValueCollection existant dans un dictionnaire. J'ai le code suivant ci-dessous pour le faire, mais apparemment, Add n'accepte pas que mes clés et mes valeurs soient en tant que chaînes.
IDictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>();
public void copyFromNameValueCollection (NameValueCollection a)
{
foreach (var k in a.AllKeys)
{
dict.Add(k, a[k]);
}
}
Remarque: NameValueCollection contient des clés et des valeurs de chaîne. Par conséquent, je souhaite simplement fournir ici une méthode permettant de les copier dans un dictionnaire generic .
Cela n'a aucun sens d'utiliser les génériques ici, car vous ne pouvez pas affecter string
s à un type générique arbitraire:
IDictionary<string, string> dict = new Dictionary<string, string>();
public void copyFrom(NameValueCollection a)
{
foreach (var k in a.AllKeys)
{
dict.Add(k, a[k]);
}
}
bien que vous deviez probablement créer une méthode pour créer un nouveau dictionnaire:
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;
}
que vous pouvez utiliser comme:
NameValueCollection nvc = //
var dictionary = nvc.ToDictionary();
Si vous voulez un moyen général de convertir les chaînes de la collection en types clé/valeur requis, vous pouvez utiliser des convertisseurs de type:
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;
}
Méthode d'extension plus linq:
public static Dictionary<string, string> ToDictionary(this NameValueCollection nvc) {
return nvc.AllKeys.ToDictionary(k => k, k => nvc[k]);
}
//example
var dictionary = nvc.ToDictionary();
parameters.AllKeys.ToDictionary(t => t, t => parameters[t]);
Utilisez LINQ:
public static IDictionary<string, string> ToDictionary(this NameValueCollection collection)
{
return collection.Cast<string>().ToDictionary(k => k, v => collection[v]);
}
Usage:
IDictionary<string, string> dic = nv.ToDictionary();
Version très courte
var dataNvc = HttpUtility.ParseQueryString(data);
var dataCollection = dataNvc.AllKeys.ToDictionary(o => o, o => dataNvc[o]);
Si vous savez que votre dictionnaire contiendra toujours des chaînes, spécifiez-le pour contenir des chaînes au lieu de rendre votre classe générique:
IDictionary<string, string> dict = new Dictionary<string, string>();
Avec cela, les choses "fonctionneront" telles que rédigées (sans la spécification de méthode générique).
Si vous souhaitez que cette classe soit générique et contienne des données génériques, vous avez besoin d'un moyen de convertir string
en TKey
et string
en TValue
. Vous pouvez fournir aux délégués votre méthode de copie pour ce faire:
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]));
}
}
Vous devrez ensuite passer un délégué qui effectuera la conversion de chaîne en TValue
et chaîne en TKey
.
Vous ne devez pas oublier EqualityComparer. Mais ce n'est pas une propriété publique. Donc, vous devriez utiliser la réflexion pour l'obtenir.
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;
}