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

C# 如何比较相同但无约束泛型类型的两个元素是否相等?,c#,generics,class,struct,equals,C#,Generics,Class,Struct,Equals,可能重复: 我有以下泛型类,编译器抱怨“运算符”!=”不能应用于“TValue”和“TValue”类型的操作数”(请参阅): 公共类示例 { 私人价值(t值);; 公共价值 { 获取{返回_值;} 设置 { 如果(_值!=值)/ 值类型的等于() 引用类型的ReferenceEquals() 你试过这样的东西吗 public class Example<TValue> { private TValue _value; public TValue Value

可能重复:

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

公共类示例
{
私人价值(t值);;
公共价值
{
获取{返回_值;}
设置
{
如果(_值!=值)/
  • 值类型的等于()
  • 引用类型的ReferenceEquals()

你试过这样的东西吗

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

            if (!object.Equals(_value, value))
            {
                _value = value;
                OnPropertyChanged("Value");
            }
        }
    }
}
公共类示例
{
私人价值(t值);;
公共价值
{
获取{返回_值;}
设置
{
如果(!object.Equals(_value,value))
{
_价值=价值;
不动产变更(“价值”);
}
}
}
}

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

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


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

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");
            }
        }
    }
}
公共类示例,其中TValue:IComparable
{
私人价值(t值);;
公共价值
{
获取{返回_值;}
设置
{
如果(_value.CompareTo(value)!=0)
{
_价值=价值;
不动产变更(“价值”);
}
}
}
}
三个选项:

  • 约束TValue以实现
    IEquatable
    ,然后调用
    x.Equals(y)
  • 获取另一个类型为
    IEqualityComparer
    的参数并使用该参数
  • 使用
    EqualityComparer.Default
    执行比较
当然,您可以始终混合和匹配选项2和3-默认为默认比较器,但也允许提供特定的比较器。

公共静态布尔运算符==(EntityBase entity1,EntityBase entity2)
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;
        }
{ 如果((对象)entity1==null&&(对象)entity2==null) { 返回true; } 如果((对象)entity1==null | |(对象)entity2==null) { 返回false; } if(Comparer.Default.Compare(entity1.Id,entity2.Id)!=0) { 返回false; } 返回true; }
为什么不能对值类型使用.Equals?默认情况下,如果对引用类型调用“object.Equals(a,b)”,则将调用“object.ReferenceEquals(a,b)”。@TcKs:默认情况下,您无法确定是否在派生类中重写了Equals。@Iepie:是的,如果重写了相等运算符(和Equals方法),则此方法应该比默认实现更了解如何比较两个对象。因此,它应该返回正确的Resultl。@Tcks:True,就我而言,brainfart:)我宁愿避免反射或以其他方式区分这两种情况。目前,我使用抽象基并两次实现这些位:-/您使用的反射是什么?正在做什么typeof(TValue)是编译时常量,检查该类型实际上不会花费任何成本。是的,这也是我对CS0019的理解。表示默认情况下,将按位比较值类型,否则将使用Equals()方法。这就是我要寻找的。请注意,这将对值类型产生装箱惩罚。
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;
        }