Wie Sie sehen in den Bezugsquellen können, Namevaluecollection erbt von Nameobjectcollectionbase .
Sie nehmen also den Basistyp, rufen die private Hashtabelle per Reflektion ab und prüfen, ob sie einen bestimmten Schlüssel enthält.
Damit es auch in Mono funktioniert, müssen Sie den Namen der Hashtabelle in Mono sehen, was Sie hier sehen können (m_ItemsContainer), und das Monofeld abrufen, wenn die anfängliche FieldInfo null ist (Mono- Laufzeit).
So was
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);
}
}
Für ultrareinen, nicht reflektierenden .NET 2.0-Code können Sie die Schlüssel durchlaufen, anstatt die Hash-Tabelle zu verwenden. Dies ist jedoch langsam.
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;
}