如何比较相同但不受约束的泛型类型的两个元素是否相等?

时间:2008-12-03 11:44:41

标签: c# generics class struct equals

  

可能重复:
  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");
            }
        }
    }
}

如果我将TValue约束为class,我可以使用Object.Equals()。既然我需要这个结构和类,我会很高兴,如果我可以避免这一点。

所以问题是,如何比较相同但不受约束的泛型类型的两个元素是否相等?

6 个答案:

答案 0 :(得分:12)

你尝试过这样的事吗?

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

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

答案 1 :(得分:7)

三个选项:

  • 限制TValue实施IEquatable<TValue>,然后致电x.Equals(y)
  • 使用IEqualityComparer<TValue>类型的另一个参数并使用该
  • 使用EqualityComparer<TValue>.Default执行比较

您可以随时混合和匹配选项2和3 - 默认为默认比较器,但也允许提供特定的比较器。

答案 2 :(得分:2)

  • 值类型的等号()
  • 参考类型的ReferenceEquals()

答案 3 :(得分: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");
            }
        }
    }
}

答案 4 :(得分:0)

我认为!=运算符不能在此处应用,因为有些情况下无法使用它。例如,除非比较运算符(!= ==)过载,否则!=不能用于比较结构。

当然,您可以比较语言结构,例如int != int,但我不确定这是如何实现的。

因此,因为TValue可以是自定义结构,所以它不能使用!=运算符。

答案 5 :(得分: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;
        }