2014-11-13 2 views
0

안녕하세요 저는 C#의 새로운 기능이며 약간의 질문이 있습니다 : list1.contains(product) 메서드를 호출하면 Equals 메서드를 재정의해야하는 Java와 비슷합니까?C#의 개체 비교

예인 경우? 이것을하는 방법입니까?

public partial class product 
{ 
    public product() 
    { 
    } 

    public int idProduct { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (this == obj) 
     { 
      return true; 
     } 
     if (obj == null) 
     { 
      return false; 
     } 
     if (this.GetType() != obj.GetType()) 
     { 
      return false; 
     } 

     product other = (product)obj; 
     if (idProduct != other.idProduct) 
     { 
      return false; 
     } 
     return true; 
    } 
} 

답변

3

예. 클래스에 동등한 의미를 제공하려면 Equals를 재정의해야합니다. 기본적으로 참조 동일성이 적용됩니다.

당신의 Equals 메서드는 작동하지만 C#에서는 == 연산자도 재정의 할 수 있습니다. 따라서 Equals 메서드에서 사용하는 것이 안전하지 않을 수도 있습니다. 이 기준 비교를 ReferenceEquals을 사용하는 것이 좋을 것이다 :

public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(obj,null)) 
     { 
      return false; 
     } 
     if (ReferenceEquals(this,obj)) 
     { 
      return true; 
     } 
     if (this.GetType() != obj.GetType()) 
     { 
      return false; 
     } 
     product other = (product)obj; 
     if (idProduct != other.idProduct) 
     { 
      return false; 
     } 
     return true; 
    } 
+0

+1. 대부분의 Linq/콜렉션 메소드는 비교자를 인수로 사용하므로 커스텀'Equal'을 구현하는 것은 꼭 필요한 것은 아닙니다. –

+0

@AlexeiLevenkov 그게 무슨 소리 야? –

+0

@HamletHakobyan [Enumerable.Contains (..., IEqualityComparer )] (http://msdn.microsoft.com/en-us/library/vstudio/bb339118%28v=vs.100%29.aspx) –

0

그것은 당신이 IEquatable<T>를 구현하여 코드를 조금 단축 할 수 있음을 언급 아마 가치가있다. 당신의 일반적인 목록에서 유형이 캐스트를 방지 IEquatable을 구현하는 경우

List<T>.ContainsIEquatable<T>.Equals를 호출합니다 :

또한
public class product : IEquatable<product> 
{ 
    public int idProduct { get; set; } 

    // List<product>.Contains will call IEquatable<product>.Equals if available. 
    public bool Equals(product other) 
    { 
     return ReferenceEquals(other, this) || other.idProduct == this.idProduct; 
    } 

    // Note: you should still override object.Equals. 
    public override bool Equals(object other) 
    { 
     return this.Equals(other as product); 
    } 
} 

C에서 # 클래스는 일반적으로 PascalCased하지 camelCased 있습니다.

1

@driis answer뿐만 아니라, 당신은 또한 같은 새로운 IEqualityComparer<Product> 만들 수 있습니다

public sealed class ProductEqualityComparer : IEqualityComparer<Product> 
{ 
    public bool Equals(Product x, Product y) 
    { 
     if (ReferenceEquals(x, y)) return true; 
     if (ReferenceEquals(x, null)) return false; 
     if (ReferenceEquals(y, null)) return false; 
     if (x.GetType() != y.GetType()) return false; 
     return x.idProduct == y.idProduct; 
    } 

    public int GetHashCode(Product obj) 
    { 
     return obj.idProduct; 
    } 
} 

을 그리고 당신이 통과 할 수 Comparer-Contains 같은 : list1List<Product>으로 정의된다

if (list1.Contains(product, new ProductEqualityComparer())) 
{ 

} 

:

Product product = new Product { idProduct = 1 }; 
List<Product> list1 = new List<Product> 
{ 
    new Product{idProduct = 1}, 
    new Product{idProduct = 2} 
}; 
우리는 당신이 IEqualityComparer<T> 인터페이스를 구현하는 대신 EqualityComparer<T> 클래스 에서 파생하는 것이 좋습니다 MSDN states

때문에

또는 당신은 EqualsGetHashCode를 오버라이드 (override) 다음 EqualityComparer<T>에서 상속 할 수 있습니다, 평등에 대한 때문에 EqualityComparer<T> 클래스를 테스트를 사용하여IEquatable<T>.Equals 메서드 대신 Object.Equals 메서드를 사용하십시오. Dictionary<TKey, TValue> 클래스 및 기타 컬렉션의 Contains, IndexOf, LastIndexOf 및 Remove 메서드와 일치합니다.

public sealed class ProductEqualityComparer : EqualityComparer<Product> 
{ 
    public override bool Equals(Product x, Product y) 
    { 
     if (ReferenceEquals(x, y)) return true; 
     if (ReferenceEquals(x, null)) return false; 
     if (ReferenceEquals(y, null)) return false; 
     if (x.GetType() != y.GetType()) return false; 
     return x.idProduct == y.idProduct; 
    } 

    public override int GetHashCode(Product obj) 
    { 
     return obj.idProduct; 
    } 
}