c#比较两个通用值

时间:2009-01-28 16:19:59

标签: c# generics

  

可能重复:
  Can’t operator == be applied to generic types in C#?

我编写了这样的代码:

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

    return (valueInDB != valueFromView);
}

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

4 个答案:

答案 0 :(得分:116)

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

使用EqualityComparer<T>。默认为您执行此操作。这将处理仅为==提供运算符重载的类型,而不是:

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

一般来说,实现==运算符而不是至少其中一个运算符也是一个非常糟糕的主意,所以这不太可能是一个问题。

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

    return !EqualityComparer<T>.Default.Equals(value1 , value2);
}

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

答案 1 :(得分:4)

那应该适合你。

public bool test<T>(T test, T test2) where T : class
{
    return (test != test2);
}

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

答案 2 :(得分:3)

您的类型需要实现IComparableIEquatable界面。

或许您需要将!= b重写为!(a == b),或明确调用CompareTo()或Equals()方法。

答案 3 :(得分:0)

您可以在对象上重载.Equals()方法,并将评估更改为:

return (!valueInDB.Equals(valueFromView));

假设valueInDB和valueFromView是对象。您的示例变量的名称与compare中使用的变量名称不同,因此我不得不假设。

编辑:3秒钟击败!关于重载的注意事项,如果你需要比较一个类型中的值,那么Object类中的基本.Equals()是不够的,因为它只会对复杂类型进行内存比较。您需要重载并提供实现比较对象的方式。