2012-01-27 11 views

Respuesta

17

no veo razón por la que había necesidad de una. Si desea crear un código hash basado en el valor por defecto GetHashCode por 3 artículos diferentes, a continuación, sólo tiene que utilizar:

Tuple.Create(lastName, firstName, gender).GetHashCode() 

Eso se reducen hasta el equivalente de:

int h1 = lastName.GetHashCode(); 
int h2 = firstName.GetHashCode(); 
int h3 = gender.GetHashCode(); 
return (((h1 << 5) + h1)^(((h2 << 5) + h2)^h3)); 

que es bastante razonable para tal combinación de propósito general.

mismo modo:

Tuple.Create(lastName, firstName, gender).Equals(Tuple.Create(lastName2, firstName2, gender2)) 

se reduciría hasta el equivalente de llamar:

return ((lastName == null && lastName2 == null) || (lastName != null && lastName.Equals(lastName2))) 
    && ((firstName == null && firstName2 == null) || (firstName != null && firstName.Equals(lastName2))) 
    && ((gender == null && gender2 == null) || (gender != null && gender.Equals(lastName2))); 

Una vez más, casi tan bueno como se podría esperar.

+1

+1: las tuplas y los tipos anónimos son excelentes para implementar GetHashCode(), Equals() y ToString() – millimoose

+1

Buena idea al utilizar las clases 'Tuple' como acceso directo. Pero tenga en cuenta que 'Tuple.Create (...). Equals (Tuple.Create (...))' no es equivalente al método 'equals' de Guava, que sería' object.Equals (x, y) '. – LukeH

+1

@LukeH, bueno, ya que tenemos eso, y tenemos esto también, eso significa que podemos hacerlo mejor que Guava :) –

1

AFAIK ninguno. Sin embargo, escribir su propio no debe ser demasiado compleja (nb usando una variación del hash Bernstein):

public static class Objects 
{ 
    public static bool Equals<T>(T item1, T item2, Func<T, IEnumerable<object>> selector) 
    { 
    if (object.ReferenceEquals(item1, item2) return true; 
    if (item1 == null || item2 == null) return false; 

    using (var iterator1 = selector(item1).GetEnumerator()) 
    using (var iterator2 = selector(item2).GetEnumerator()) 
    { 
     var moved1 = iterator1.MoveNext(); 
     var moved2 = iterator2.MoveNext(); 
     if (moved1 != moved2) return false; 
     if (moved1 && moved2) 
     { 
     if (!Equals(iterator1.Current, iterator2.Current)) return false; 
     } 
    } 
    return true; 
    } 

    public static bool Equals(object item1, object item2) 
    { 
    return object.Equals(item1, item2); 
    } 

    public static int GetHashCode(params object[] objects) 
    { 
    unchecked 
    { 
     int hash = 17; 
     foreach (var item in objects) 
     { 
     hash = hash * 31 + item.GetHashCode(); 
     } 
     return hash; 
    } 
    } 
} 
+0

Su método 'Equals' es exactamente el mismo que el método estático incorporado' object.Equals (x, y) ': http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx – LukeH

+0

Gracias @LukeH, ¿por qué reinventar la rueda? Respuesta actualizada –

+0

'Igual' no es más útil que la implementación estándar heredada. Debe ser posible establecer qué campos se deben considerar para la igualdad. – deamon

Cuestiones relacionadas