Подтвердить что ты не робот

Foreach KeyValuePair в NameValueCollection?

У меня есть этот код:

NameValueCollection nv = HttpUtility.ParseQueryString(queryString);        
foreach (KeyValuePair<String,String> pr in nv) {
    //process KeyValuePair          
}

Это компилируется, но когда я пытаюсь запустить его, я получаю InvalidCastException.

Почему это? Почему я не могу использовать KeyValuePair для итерации по NameValueCollection, и что я должен использовать вместо этого?

4b9b3361

Ответ 1

Прежде всего, NameValueCollection не использует KeyValuePair<String,String>. Кроме того, foreach предоставляет только ключ:

NameValueCollection nv = HttpUtility.ParseQueryString(queryString);        
foreach (string key in nv) {
    var value = nv[key];

}

Ответ 2

Для дальнейшего использования вы также можете использовать этот синтаксис:

foreach(string key in Request.QueryString)
{
    var value = Request.QueryString[key];
}

Ответ 3

Вы не можете сделать это напрямую, но вы можете создать метод расширения следующим образом:

public static IEnumerable<KeyValuePair<string, string>> AsKVP(
        this NameValueCollection source
)
{
    return source.AllKeys.SelectMany(
        source.GetValues,
        (k, v) => new KeyValuePair<string, string>(k, v));
}

Затем вы можете сделать:

NameValueCollection nv = HttpUtility.ParseQueryString(queryString);
foreach (KeyValuePair<String,String> pr in nv.AsKVP()) {
    //process KeyValuePair          
}

Примечание: вдохновлено этим. SelectMany требуется для обработки дубликатов ключей.

версия vb.net:

<Extension>
Public Function AsKVP(
        source As Specialized.NameValueCollection
) As IEnumerable(Of KeyValuePair(Of String, String))
    Dim result = source.AllKeys.SelectMany(
        AddressOf source.GetValues,
        Function(k, v) New KeyValuePair(Of String, String)(k, v))
    Return result
End Function

Ответ 4

Другой метод расширения для учебных целей:

    public static IEnumerable<KeyValuePair<string, string>> ToIEnumerable(this NameValueCollection nvc)
    {
        foreach (string key in nvc.AllKeys)
        {
            yield return new KeyValuePair<string, string>(key, nvc[key]);
        }
    }

Ответ 5

NameValueCollection использует счетчик old-skool:

        var enu = ConfigurationManager.AppSettings.GetEnumerator();

        while(enu.MoveNext())
        {
            string key = (string)enu.Current;
            string value = ConfigurationManager.AppSettings[key];
        }

Ответ 6

Мне понравилось, и он работает:

 foreach (string akey in request.Query.Keys.Cast<string>())
     writer.WriteLine(akey + " = " + request.Query[akey]);