Como puede ver en las fuentes de referencia, NameValueCollection hereda de NameObjectCollectionBase .
Entonces, toma el tipo base, obtiene la tabla hash privada a través de la reflexión y verifica si contiene una clave específica.
Para que funcione también en Mono, debe ver cuál es el nombre de la tabla hash en mono, que es algo que puede ver aquí (m_ItemsContainer), y obtener el campo mono, si FieldInfo inicial es nulo (mono- tiempo de ejecución).
Me gusta esto
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);
}
}
para el código .NET 2.0 ultrapuro no reflectante, puede recorrer las teclas, en lugar de usar la tabla hash, pero eso es lento.
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;
}