测试相等于默认值

Gre*_*reg 53 c# generics equality

以下内容无法编译:

public void MyMethod<T>(T value)
{
    if (value == default(T))
    {
        // do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*ell 79

为了避免拳击struct/ Nullable<T>,我会使用:

if (EqualityComparer<T>.Default.Equals(value,default(T)))
{
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

这支持任何T实现IEquatable<T>,object.Equals用作备份,并自动处理null等(并提升运算符Nullable<T>).

还有Comparer<T>.Default处理比较测试.这可以处理T该工具IComparable<T>,IComparable再次回到- 再次处理null和解除操作员.

  • 更好的表现(减少拳击); 考虑`T = int`; 调用`object.Equals`它必须包装`value`和`default(T)` - 这是两个额外的堆分配+ GC.使用`EqualityComparer <T>`它有3个不同的底层实现 - `class`,`Nullable <T>`和`struct` - 然后它可以做任何事情(包括`null`测试)而不用**任何**拳击.确定要使用哪种实现的工作仅针对每种类型进行一次并进行缓存,因此仍然非常快. (12认同)

Gra*_*ton 28

关于什么

object.Equals(value, default(T))
Run Code Online (Sandbox Code Playgroud)

  • +1。测试。适用于各种类型:`MyMethod(0); MyMethod&lt;String&gt;(null); MyMethod&lt;DataSet&gt;(null);` - 在每种情况下都返回 true。 (2认同)
  • 这样做的缺点是,它会不必要地对值类型进行装箱(这就是为什么首选“EqualityComparer&lt;T&gt;.Default.Equals”) (2认同)