ループせずに NameValueCollection にキーが存在するかどうかをすばやく簡単に確認する方法はありますか?
Dictionary.ContainsKey() などを探します。
もちろん、これを解決する方法はたくさんあります。誰かが私の脳のかゆみを掻くのを手伝ってくれるかどうか疑問に思っています.
ループせずに NameValueCollection にキーが存在するかどうかをすばやく簡単に確認する方法はありますか?
Dictionary.ContainsKey() などを探します。
もちろん、これを解決する方法はたくさんあります。誰かが私の脳のかゆみを掻くのを手伝ってくれるかどうか疑問に思っています.
MSDNから:
このプロパティは、次の場合に null を返します。
1) 指定されたキーが見つからない場合。
したがって、次のことができます。
NameValueCollection collection = ...
string value = collection[key];
if (value == null) // key doesn't exist
2) 指定されたキーが見つかり、それに関連付けられた値が null の場合。
collection[key]
base.Get()
次に、パフォーマンス O(1)base.FindEntry()
で内部的に使用する呼び出し。Hashtable
このメソッドは、キーがコレクション内にあり、関連付けられた値が null の場合を処理します。
private static bool ContainsKey(this NameValueCollection collection, string key) =>
collection.Get(key) != null || collection.AllKeys.Contains(key);
はい、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))
{
...
}
参照ソースでわかるように、NameValueCollectionはNameObjectCollectionBaseから継承されます。
したがって、基本型を取得し、リフレクションを介してプライベート ハッシュ テーブルを取得し、特定のキーが含まれているかどうかを確認します。
Mono でも機能させるには、ハッシュテーブルの名前を mono で確認する必要があります。これはここで確認できます(m_ItemsContainer)。最初の FieldInfo が null の場合は mono-field を取得します (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;
}
メソッドを使用して、NameValueCollection に指定されたキーが含まれていない場合にメソッドが返されるかどうかGet
を確認できます。null
null
MSDNを参照してください。
これは、新しい方法を導入する必要のない解決策になる可能性もあります。
item = collection["item"] != null ? collection["item"].ToString() : null;
コレクションのサイズが小さい場合は、rich.okelly が提供するソリューションを使用できます。ただし、コレクションが大きいということは、ディクショナリの生成がキー コレクションの検索よりも著しく遅くなる可能性があることを意味します。
また、NameValueCollection が変更された可能性があるさまざまな時点でキーを検索する使用シナリオの場合、毎回辞書を生成すると、キー コレクションを検索するよりも遅くなる可能性があります。
VB では次のようになります。
if not MyNameValueCollection(Key) is Nothing then
.......
end if
C# では、次のようにする必要があります。
if (MyNameValueCollection(Key) != null) { }
そうあるべきかどうかはわかりませんnull
が""
、これは役立つはずです。
NameValueCollection n = Request.QueryString;
if (n.HasKeys())
{
//something
}
戻り値の型: System.Boolean NameValueCollection に null 以外のキーが含まれている場合は true。それ以外の場合は false。リンク