Есть ли быстрый и простой способ проверить, существует ли ключ в NameValueCollection, не просматривая его?
Ищете что-то вроде Dictionary.ContainsKey () или подобное.
Конечно, есть много способов решить эту проблему. Просто интересно, может ли кто-нибудь помочь мне избавиться от зуда в мозгу.
c#
.net
namevaluecollection
Мухаммад Юссуф
источник
источник
Ответы:
Из MSDN :
Итак, вы можете просто:
NameValueCollection collection = ... string value = collection[key]; if (value == null) // key doesn't exist
collection[key]
вызываетbase.Get()
then,base.FindEntry()
который внутренне используетHashtable
с производительностью O (1).источник
0
равныйnull
... sryИспользуйте этот метод:
private static bool ContainsKey(this NameValueCollection collection, string key) { if (collection.Get(key) == null) { return collection.AllKeys.Contains(key); } return true; }
Он наиболее эффективен
NameValueCollection
и не зависит от того, содержит ли коллекцияnull
значения или нет.источник
using System.Linq;
при использовании этого раствора.Я не думаю, что любой из этих ответов является правильным / оптимальным. NameValueCollection не только не делает различий между нулевыми и пропущенными значениями, но и не чувствителен к регистру в отношении ключей. Таким образом, я думаю, что полное решение будет:
public static bool ContainsKey(this NameValueCollection @this, string key) { return @this.Get(key) != null // I'm using Keys instead of AllKeys because AllKeys, being a mutable array, // can get out-of-sync if mutated (it weirdly re-syncs when you modify the collection). // I'm also not 100% sure that OrdinalIgnoreCase is the right comparer to use here. // The MSDN docs only say that the "default" case-insensitive comparer is used // but it could be current culture or invariant culture || @this.Keys.Cast<string>().Contains(key, StringComparer.OrdinalIgnoreCase); }
источник
Да, вы можете использовать Linq для проверки
AllKeys
свойства:using System.Linq; ... collection.AllKeys.Contains(key);
Однако
Dictionary<string, string[]>
для этой цели больше подходит a , возможно, созданный с помощью метода расширения:public static void Dictionary<string, string[]> ToDictionary(this NameValueCollection collection) { return collection.Cast<string>().ToDictionary(key => key, key => collection.GetValues(key)); } var dictionary = collection.ToDictionary(); if (dictionary.ContainsKey(key)) { ... }
источник
collection[key]
внутренне используетHashtable
O (1)collection[key]
делает различий между отсутствующим ключом и нулевым значением, сохраненным для этого ключа.Вы можете использовать
Get
метод и проверить,null
как метод вернет,null
если NameValueCollection не содержит указанный ключ.См. MSDN .
источник
index
изkey
вызвать метод. Не так ли?Если размер коллекции невелик, вы можете воспользоваться решением, предоставленным rich.okelly. Однако большая коллекция означает, что создание словаря может быть заметно медленнее, чем простой поиск в коллекции ключей.
Кроме того, если ваш сценарий использования ищет ключи в разные моменты времени, где NameValueCollection мог быть изменен, создание словаря каждый раз, опять же, может быть медленнее, чем просто поиск в коллекции ключей.
источник
Это также может быть решением без необходимости вводить новый метод:
item = collection["item"] != null ? collection["item"].ToString() : null;
источник
Как видно из справочных источников, NameValueCollection наследуется от NameObjectCollectionBase .
Итак, вы берете базовый тип, получаете частную хеш-таблицу через отражение и проверяете, содержит ли она определенный ключ.
Чтобы он работал и в Mono, вам необходимо увидеть имя хеш-таблицы в моно, которое вы можете увидеть здесь (m_ItemsContainer), и получить монополе, если исходное поле FieldInfo имеет значение null (mono- время выполнения).
Как это
public static class ParameterExtensions { private static System.Reflection.FieldInfo InitFieldInfo() { System.Type t = typeof(System.Collections.Specialized.NameObjectCollectionBase); System.Reflection.FieldInfo fi = t.GetField("_entriesTable", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); if(fi == null) // Mono fi = t.GetField("m_ItemsContainer", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); return fi; } private static System.Reflection.FieldInfo m_fi = InitFieldInfo(); public static bool Contains(this System.Collections.Specialized.NameValueCollection nvc, string key) { //System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection(); //nvc.Add("hello", "world"); //nvc.Add("test", "case"); // The Hashtable is case-INsensitive System.Collections.Hashtable ent = (System.Collections.Hashtable)m_fi.GetValue(nvc); return ent.ContainsKey(key); } }
для сверхчистого неотражающего кода .NET 2.0 вы можете перебирать ключи вместо использования хэш-таблицы, но это медленно.
private static bool ContainsKey(System.Collections.Specialized.NameValueCollection nvc, string key) { foreach (string str in nvc.AllKeys) { if (System.StringComparer.InvariantCultureIgnoreCase.Equals(str, key)) return true; } return false; }
источник
В VB это:
if not MyNameValueCollection(Key) is Nothing then ....... end if
В C # должно быть просто:
if (MyNameValueCollection(Key) != null) { }
Не уверен, должно ли это быть
null
или""
это должно помочь.источник
Dictionary
структуру данныхMyNameValueCollection[Key]
, а не наMyNameValueCollection(Key)
, которая ожидает вызова метода.Я использую эту коллекцию, когда работал с коллекцией небольших элементов.
Где элементов много, думаю нужно использовать "Словарь". Мой код:
NameValueCollection ProdIdes; string prodId = _cfg.ProdIdes[key]; if (string.IsNullOrEmpty(prodId)) { ...... }
Или можно использовать это:
string prodId = _cfg.ProdIdes[key] !=null ? "found" : "not found";
источник
Имейте в виду, что ключ может быть не уникальным и что сравнение обычно чувствительно к регистру. Если вы хотите просто получить значение первого совпадающего ключа и не беспокоиться о регистре, используйте это:
public string GetQueryValue(string queryKey) { foreach (string key in QueryItems) { if(queryKey.Equals(key, StringComparison.OrdinalIgnoreCase)) return QueryItems.GetValues(key).First(); // There might be multiple keys of the same name, but just return the first match } return null; }
источник
NameValueCollection n = Request.QueryString; if (n.HasKeys()) { //something }
Возвращаемое значение Тип: System.Boolean true, если NameValueCollection содержит ключи, которые не равны нулю; в противном случае - ложь. ССЫЛКА НА САЙТ
источник