2008-12-03 18 views
8

thể trùng lặp:
Can’t operator == be applied to generic types in C#?Làm thế nào để so sánh hai yếu tố của cùng loại nhưng không bị ràng buộc loại chung cho bình đẳng?

Tôi đã có lớp generic sau và trình biên dịch phàn nàn rằng "Operator '!=' cannot be applied to operands of type 'TValue' and 'TValue'" (xem CS0019):

public class Example<TValue> 
{ 
    private TValue _value; 
    public TValue Value 
    { 
     get { return _value; } 
     set 
     { 
      if (_value != value) // <<-- ERROR 
      { 
       _value= value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 
} 

Nếu tôi constrain TValue to class, tôi có thể sử dụng Object.Equals(). Vì tôi cần điều này cho cả hai cấu trúc và lớp tôi sẽ rất vui nếu tôi có thể tránh được điều đó.

Vì vậy, câu hỏi đặt ra là, làm cách nào để tôi có thể so sánh hai yếu tố thuộc cùng loại chung nhưng không bị ràng buộc cho sự bình đẳng?

+2

Tại sao bạn không thể sử dụng .Thanh toán cho các loại giá trị? –

+0

Theo mặc định, nếu bạn gọi "object.Equals (a, b)" trên các loại tham chiếu, thì "object.ReferenceEquals (a, b)" sẽ được gọi. – TcKs

+0

@TcKs: Theo mặc định, bạn không thể chắc chắn nếu Equals đã được overriden trong một lớp dẫn xuất. – leppie

Trả lời

12

Bạn có thử một cái gì đó như thế này?

public class Example<TValue> 
{ 
    private TValue _value; 
    public TValue Value 
    { 
     get { return _value; } 
     set 
     { 

      if (!object.Equals(_value, value)) 
      { 
       _value = value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 
} 
+0

http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx nói rằng theo loại giá trị mặc định sẽ được so sánh bitwise, nếu không phương thức Equals() được sử dụng. Đó là những gì tôi đang tìm kiếm. –

+4

Lưu ý rằng điều này sẽ phải chịu hình phạt quyền anh đối với các loại giá trị. –

2
  • Equals() với nhiều loại giá trị
  • ReferenceEquals() với nhiều loại tài liệu tham khảo
+1

Tôi muốn tránh phải phản ánh hoặc phân biệt hai trường hợp. Hiện tại tôi đang sử dụng cơ sở trừu tượng và triển khai các bit này hai lần: -/ –

+0

Bạn đang sử dụng phản chiếu nào? Làm một typeof (TValue) là một hằng số thời gian biên dịch, và kiểm tra loại đó sẽ không thực sự chi phí bất cứ điều gì. – leppie

0

Tôi nghĩ rằng các nhà điều hành != không thể áp dụng ở đây vì có những trường hợp nó không thể được sử dụng. Ví dụ: != không thể được sử dụng để so sánh cấu trúc, trừ khi toán tử so sánh (==!=) bị quá tải.

Tất nhiên, bạn có thể so sánh cấu trúc ngôn ngữ, chẳng hạn như int != int, nhưng tôi không chắc cách thực hiện điều này.

Vì vậy, vì TValue có thể là cấu trúc tùy chỉnh, nên không thể sử dụng toán tử !=.

+0

Vâng, đó cũng là sự hiểu biết của tôi về CS0019. –

1

Có phải tùy chọn IComparable không?

public class Example<TValue> where TValue: IComparable 
{ 
    private TValue _value; 
    public TValue Value 
    { 
     get { return _value; } 
     set 
     { 

      if (_value.CompareTo(value) != 0) 
      { 
       _value = value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 
} 
7

Ba lựa chọn:

  • Constrain TValue để thực hiện IEquatable<TValue> và sau đó gọi x.Equals(y)
  • Đi một tham số có kiểu IEqualityComparer<TValue> và sử dụng rằng
  • Sử dụng EqualityComparer<TValue>.Default để thực hiện các so sánh

Bạn luôn có thể trộn và kết hợp các tùy chọn 2 và 3, tất nhiên - mặc định cho trình so sánh mặc định, nhưng cũng cho phép một tùy chọn cụ thể được cung cấp.

0
public static bool operator ==(EntityBase<T> entity1, EntityBase<T> entity2) 
     { 
      if ((object)entity1 == null && (object)entity2 == null) 
      { 
       return true; 
      } 

      if ((object)entity1 == null || (object)entity2 == null) 
      { 
       return false; 
      } 

      if (Comparer<T>.Default.Compare(entity1.Id, entity2.Id) != 0) 
      { 
       return false; 
      } 

      return true; 
     } 
Các vấn đề liên quan