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

时间:2022-06-11 13:50:50

Possible Duplicate:
Can’t operator == be applied to generic types in C#?

可能重复:不能将运算符==应用于C#中的泛型类型?

I've got the following generic class and the compiler complains that "Operator '!=' cannot be applied to operands of type 'TValue' and 'TValue'" (see CS0019):

我有以下泛型类,编译器抱怨“运算符'!='不能应用于'TValue'和'TValue'类型的操作数”(参见CS0019):

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

If I constrain TValue to class, I could use Object.Equals(). Since I need this for boths structs and classes I'd be very happy if I could avoid that though.

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

So the question is, how can I compare two elements of the same but unconstrained generic type for equality?

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

6 个解决方案

#1


12  

Did you try something like this?

你尝试过这样的事吗?

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

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

#2


7  

Three options:

  • Constrain TValue to implement IEquatable<TValue> and then call x.Equals(y)
  • 约束TValue实现IEquatable 然后调用x.Equals(y)

  • Take another parameter of type IEqualityComparer<TValue> and use that
  • 取另一个IEqualityComparer 类型的参数并使用它

  • Use EqualityComparer<TValue>.Default to perform the comparisons
  • 使用EqualityComparer .Default执行比较

You could always mix and match options 2 and 3, of course - default to the default comparer, but also allow a specific one to be provided.

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

#3


2  

  • Equals() for value types
  • 值类型的Equals()

  • ReferenceEquals() for reference types
  • ReferenceEquals()用于引用类型

#4


1  

Is IComparable an option?

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");
            }
        }
    }
}

#5


0  

I think the != operator cannot be applied here because there are cases where it can't be used. For instance, != can't be used for comparing structs, unless the compare operators (== !=) are overloaded.

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

Of course, you can compare language structs, like int != int, but I'm not sure how this is implemented.

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

So, because TValue can be a custom struct, it cannot use the != operator.

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

#6


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;
        }

#1


12  

Did you try something like this?

你尝试过这样的事吗?

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

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

#2


7  

Three options:

  • Constrain TValue to implement IEquatable<TValue> and then call x.Equals(y)
  • 约束TValue实现IEquatable 然后调用x.Equals(y)

  • Take another parameter of type IEqualityComparer<TValue> and use that
  • 取另一个IEqualityComparer 类型的参数并使用它

  • Use EqualityComparer<TValue>.Default to perform the comparisons
  • 使用EqualityComparer .Default执行比较

You could always mix and match options 2 and 3, of course - default to the default comparer, but also allow a specific one to be provided.

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

#3


2  

  • Equals() for value types
  • 值类型的Equals()

  • ReferenceEquals() for reference types
  • ReferenceEquals()用于引用类型

#4


1  

Is IComparable an option?

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");
            }
        }
    }
}

#5


0  

I think the != operator cannot be applied here because there are cases where it can't be used. For instance, != can't be used for comparing structs, unless the compare operators (== !=) are overloaded.

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

Of course, you can compare language structs, like int != int, but I'm not sure how this is implemented.

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

So, because TValue can be a custom struct, it cannot use the != operator.

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

#6


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;
        }