Как решить Operator '! =' Не может применяться к операндам типов T и T,

Этот фрагмент кода работает, как и ожидалось, для типа int:

public class Test 
{
    public int Value
    {
        get => _Value;
        set
        {
            if (_Value != value)
                _Value = value;
        }
    }
    private int _Value;
}

Когда int заменяется универсальным T, компилятор жалуется:

Оператор '! =' Нельзя применить к операндам типа 'T' и 'T'

Почему это происходит и есть ли способ решить это?

Ответ 1

using System.Collections.Generic;

public class Test<T>
{
    public T Value
    {
         get => _Value; 
         set
         {
            // operator== is undefined for generic T; EqualityComparer solves this
            if (!EqualityComparer<T>.Default.Equals(_Value, value))
            {
                _Value = value;
            }
         }
    }
    private T _Value;
}

Ответ 2

T является аргументом типа и может быть class или struct. Таким образом, компилятор не позволит вам выполнять действия, которые не существуют в классах и структурах.

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

Если вы используете ключевое слово where, чтобы добавить ограничение к аргументу типа, компилятор позволит вам использовать этот метод \interface\operator

сдерживать T как class

public class Test<T> where T : class
{
     public T Value
     {
         private T _Value;

         get { return _Value; }
         set
         {
             if (_value != value)
                 _Value = value;             
         }
     }
}

Или просто используйте Equals вместо оператора ==

public class Test<T>
{
     public T Value
     {
         private T _Value;

         get { return _Value; }
         set
         {
             if (!_value.Equals(value)
                 _Value = value;             
         }
     }
}

Ответ 3

T может быть любым типом. Вы не можете использовать ==/!= для структур, если только такие операторы не определены в типе (struct).