c#比较两个通用值

ber*_*sch 68 c# generics

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

我编写了这样的代码:

public bool IsDataChanged()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return (valueInDB != valueFromView);
}
Run Code Online (Sandbox Code Playgroud)

现在该函数没有编译错误" 运算符'!='不能应用于'T'和'T'类型的操作数 ".我该怎么做才能使这个功能起作用?

Shu*_*oUk 123

你不能在泛型类型上使用运算符(除了foo == null,这是特殊的),除非你添加T:class来表示它是一个引用类型(然后foo == bar是合法的)

使用EqualityComparer<T>.Default为您完成.这不适用于仅为==提供运算符重载的类型,而且也不会:

  • 实行 IEquatable<T>
  • 覆盖object.Equals()

一般来说,实现==运算符而不是至少执行其中一个操作也是一个非常糟糕的主意,所以这不是一个问题.

public bool IsDataChanged<T>()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return !EqualityComparer<T>.Default.Equals(value1 , value2);
}
Run Code Online (Sandbox Code Playgroud)

如果你不限制IEquatable<T>那么EqualityComparer默认回退可能会导致装箱与值类型一起使用时如果它们没有实现IEquatable<T>(如果你控制正在使用的类型,这可能无关紧要).我假设你正在使用=!虽然如此限制Generic类型将避免通过Object.Equals(对象)路由意外装箱.

  • 实际上,你不需要T:IEquatable <T>限制 - 没有它,使用.Equals (8认同)

Cal*_*inR 9

那应该对你有用。

public bool test<T>(T test, T test2) where T : class
{
    return (test != test2);
}
Run Code Online (Sandbox Code Playgroud)

这只是从对您的问题评论的示例中粘贴的。

  • 这只执行“Object.ReferenceEquals(test, test2)”。它不检查值是否相等。 (5认同)

dev*_*vio 5

您的类型需要实现IComparableIEquatable接口。

可能您随后需要将 a!=b 重写为 !(a==b),或者显式调用 CompareTo() 或 Equals() 方法。