【问题标题】:Test for equality to the default value测试是否等于默认值
【发布时间】:2010-12-26 03:06:29
【问题描述】:

以下内容无法编译:

public void MyMethod<T>(T value)
{
    if (value == default(T))
    {
        // do stuff
    }
}

错误:Operator '==' cannot be applied to operands of type 'T' and 'T'

我不能使用value == null,因为T 可能是一个结构。
我不能使用value.Equals(default(T)),因为value 可能是null
测试与默认值是否相等的正确方法是什么?

【问题讨论】:

标签: c# generics equality


【解决方案1】:

为了避免struct / Nullable&lt;T&gt; 的拳击,我会使用:

if (EqualityComparer<T>.Default.Equals(value,default(T)))
{
    // do stuff
}

这支持任何实现IEquatable&lt;T&gt;T,使用object.Equals作为备份,并自动处理null等(以及Nullable&lt;T&gt;的提升运算符)。

还有处理比较测试的Comparer&lt;T&gt;.Default。这将处理实现 IComparable&lt;T&gt;T,回退到 IComparable - 再次处理 null 和提升的运算符。

【讨论】:

  • 您是说EqualityComparer&lt;T&gt;.Default.EqualsObject.Equals 具有更好的性能,还是说它在某些情况下会给出正确的值而Object.Equals 不会?
  • 更好的性能(少装箱);考虑T=int;要调用object.Equals,它必须将valuedefault(T) 框起来——这是两个额外的堆分配+ GC。使用 EqualityComparer&lt;T&gt; 它有 3 种不同的底层实现 - classNullable&lt;T&gt;struct - 然后它可以在没有 any 装箱的情况下执行所有操作(包括 null 测试)。确定要使用哪个实现的工作对于每种类型只完成一次并缓存,因此仍然非常快。
  • @MarcGravell 我似乎无法让它工作。我在里面创建了一个函数来尝试确定结构是否仍然是默认值。它似乎总是返回FALSE(不是默认值)。我做错什么了吗?参考:stackoverflow.com/questions/35897019/…
【解决方案2】:

怎么样

object.Equals(value, default(T))

【讨论】:

  • 我知道它应该很简单。谢谢。
  • +1。经测试。适用于各种类型:MyMethod(0); MyMethod&lt;String&gt;(null); MyMethod&lt;DataSet&gt;(null); - 在每种情况下都返回 true。
  • 这样做的缺点是它会不必要地装箱值类型(这就是为什么EqualityComparer&lt;T&gt;.Default.Equals 是首选)
猜你喜欢
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多