2016-07-01 24 views
1

Ich habe folgende Testbeispiel:Equal Collection gibt false zurück, wenn Object IEquatable implementiert?

var a = new List<OrderRule> { 
    new OrderRule("name", OrderDirection.Ascending), 
    new OrderRule("age", OrderDirection.Descending) 
}; 

var b = new List<OrderRule> { 
    new OrderRule("name", OrderDirection.Ascending), 
    new OrderRule("age", OrderDirection.Descending) 
}; 

var r = a.SequenceEqual(b); 
Assert.Equal(a, b); 

Die Variable r wahr ist aber Assert.Equal ist falsch ...

Die OrderRule Klasse ist die folgende:

public class OrderRule : IEquatable<OrderRule> { 

    public OrderDirection Direction { get; } 
    public String Property { get; } 

    public OrderRule(String property, OrderDirection direction) { 
    Direction = direction; 
    Property = property; 
    } 

    public Boolean Equals(OrderRule other) { 
    if (other == null) 
     return false; 
    return Property.Equals(other.Property) && Direction.Equals(other.Direction); 
    } 

    public override Boolean Equals(Object obj) { 
    if (ReferenceEquals(null, obj)) 
     return false; 
    if (ReferenceEquals(this, obj)) 
     return true; 
    if (obj.GetType() != GetType()) 
     return false; 
    return Equals(obj as IncludeRule); 
    } 

    public override Int32 GetHashCode() { 
    return HashCode.Of(Property).And(Direction); 
    } 
} 

public enum OrderDirection { ASC, DESC } 

Gibt es Jedes Problem mit Assert.Equal beim Überschreiben von Equals und der Implementierung von IEquatable?

UPDATE - HashCode Helfer

public struct HashCode { 

    private readonly Int32 Value; 

    private HashCode(Int32 value) { 
    Value = value; 
    } 

    public static implicit operator Int32(HashCode hashCode) { 
    return hashCode.Value; 
    } 

    public static HashCode Of<T>(T item) { 
    return new HashCode(GetHashCode(item)); 
    } 

    public HashCode And<T>(T item) { 
    return new HashCode(CombineHashCodes(Value, GetHashCode(item))); 
    } 

    public HashCode AndEach<T>(IEnumerable<T> items) {  
    Int32 hashCode = items.Select(x => GetHashCode(x)).Aggregate((x, y) => CombineHashCodes(x, y)); 
    return new HashCode(CombineHashCodes(Value, hashCode)); 
    } 

    private static Int32 CombineHashCodes(Int32 x, Int32 y) { 
    unchecked {   
     return ((x << 5) + x)^y; 
    } 
    } 

    private static Int32 GetHashCode<T>(T item) { 
    return item == null ? 0 : item.GetHashCode(); 
    } 

} 
+1

Ihr Code funktioniert wie erwartet auf meiner Seite (nur feste Kompilierungseros - 'IncludeRule' geändert zu' OrderRule' in 'Equals' +' OrderDirection' enum Mitglieder) –

+0

Ah, fertig verpaßt das! Damm Copy Right ... Könnten Sie Ihre Erklärung als Antwort hinzufügen, damit ich sie markieren kann? –

Antwort

2

Ihr Code funktioniert wie auf meiner Seite erwartet. Ich habe nur Kompilierungseros behoben - IncludeRule geändert zu OrderRule in Equals, auch feste OrderDirection Enum-Mitglieder.

+0

Ich habe den GetHashCode in Ihren Code geändert und es hat nicht funktioniert. Übrigens, ich habe gerade meinen GetHashCode-Helfer hinzugefügt. Siehst du da etwas falsch? Aber das ist es nicht, seit ich deinen Code ausprobiert habe. –