2008-12-03 1 views
8

Можно создать дубликат:
Can’t operator == be applied to generic types in C#?Как сравнить два элемента одного и того же, но неограниченного общего типа для равенства?

У меня есть следующий общий класс и компилятор жалуется, что "Operator '!=' cannot be applied to operands of type 'TValue' and 'TValue'" (см CS0019):

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

Если я constrain TValue до class, я мог бы использовать Object.Equals(). Поскольку мне это нужно для обеих структур и классов, я был бы очень счастлив, если бы мог это избежать.

Итак, вопрос в том, как я могу сравнить два элемента одного и того же, но неограниченного общего типа для равенства?

+2

Почему вы не можете использовать .Equals для типов значений? – 2008-12-03 11:52:02

+0

По умолчанию, если вы вызываете «object.Equals (a, b)» в ссылочных типах, тогда вызывается «object.ReferenceEquals (a, b)». – TcKs 2008-12-03 11:55:36

+0

@TcKs: По умолчанию вы не можете быть уверены, что Equals был переопределен в производном классе. – leppie 2008-12-03 12:52:58

ответ

12

ли вы попробовать что-то вроде этого?

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

      if (!object.Equals(_value, value)) 
      { 
       _value = value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 
} 
2
  • Равно() для типов значений
  • ReferenceEquals() для ссылочных типов
0

Я думаю, что оператор != не может быть применен здесь, потому что есть случаи, когда не могут быть использованы. Например, != не может использоваться для сравнения структур, если только операторы сравнения (==!=) не перегружены.

Конечно, вы можете сравнить языковые структуры, например int != int, но я не уверен, как это реализовано.

Так как TValue может быть пользовательским struct, он не может использовать оператор !=.

1

Является ли IComparable опцией?

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

Три варианта:

  • Constrain TValue реализовать IEquatable<TValue>, а затем вызвать x.Equals(y)
  • Возьмем еще один параметр типа IEqualityComparer<TValue> и использовать его
  • Использование EqualityComparer<TValue>.Default для выполнения сравнения

Вы всегда можете смешивать и сопоставлять варианты 2 и 3, конечно - по умолчанию сопоставлять по умолчанию, но также допускать предоставление определенного.

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; 
     } 
Смежные вопросы