【问题标题】:Can't compare T value1 with T value2 = default(T). Why and how to do that on C#?无法将 T value1 与 T value2 = default(T) 进行比较。为什么以及如何在 C# 上做到这一点?
【发布时间】:2011-01-28 19:21:22
【问题描述】:

我正在尝试以下方法:

T value1 = el.value; // it's of type T already
T value2 = default(T);
if (value1 != value2) // gives the following error: Operator '!=' cannot be applied to operands of type 'T' and 'T'
{
    // ...
}

那么,我如何比较这两个值?为什么会出现这个错误?

提前致谢!

【问题讨论】:

  • 确保 T 实现了 ICompare-ish 类型的类,并且定义 T 的方法或类在声明中具有这些引用。

标签: c# types comparison


【解决方案1】:

您可以使用 Henk 提到的 where T : IEquatable<T> 约束,也可以忽略约束并使用:

if (!EqualityComparer<T>.Default.Equals(value1, value2))

【讨论】:

  • 我已经看到框架使用该方法来测试相等性,这似乎是一个不错的方法,即使它有点冗长。
  • 我认为这是最简单的方法。谢谢!
  • @Ani:你是对的。我忘记了没有非通用的 IEquatable 接口。将编辑。
【解决方案2】:

你周围的泛型类应该列出一个约束:T : IEquatable&lt;T&gt;

然后你必须使用value1.Equals(value2)

这一切的原因是并非所有类型都定义了运算符==

【讨论】:

  • 如果value1null,您将获得NullReferenceException
【解决方案3】:

这是怎么回事?

if (!value1.Equals(value2))

应该是“交叉对象”.. :)

【讨论】:

  • 我个人不喜欢这种不对称性。如果value1==null 当然会抛出
【解决方案4】:

并非所有类型都有== 运算符的默认实现。对于类,默认的== 操作是比较引用。对于结构,不存在这样的默认实现。

您可以在 C# 中为泛型类型参数添加类型约束。不幸的是,您无法定义强制该类型实现== 运算符的约束。你能做的最好的就是强制类型为一个类:where T: classAn article about type parameter constraints in C#

【讨论】:

    【解决方案5】:

    如果你使用 value1.equals(value2) 那么你有空值的问题。更好:
    object.equals(value1,value2)

    或者对于引用类型(小心):
    object.referenceEquals(value1,value2)

    【讨论】:

      【解决方案6】:

      试试

      Equals(value1, value2)
      

      避免空引用的好方法

      【讨论】:

        【解决方案7】:

        您可以做的另一件事是定义比较运算符(实际上是这里的差异运算符)以能够比较类型 T 的元素。编译器本身无法真正知道您在编写 value1 != value2 时的意思, 除非之前已经定义了运算符。

        要定义运算符,您可以使用

        public operator!=(T a, T b) {
            // Comparison code; returns true or false
        }
        

        【讨论】:

        • 我认为T是一个通用参数,所以这可能是不可能的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 2013-08-16
        • 2013-11-20
        • 2015-10-29
        • 1970-01-01
        • 2016-06-24
        • 2012-07-24
        相关资源
        最近更新 更多