2009-12-13 111 views
34

以下不会编译:测试平等默认值

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
什么是测试相等到默认值的正确方法?

+2

回复评论;并且对于信息来说,'EqualityComparer '是BCL使用的标准实现,例如'Dictionary <,>'。 – 2009-12-13 23:28:31

+2

http://stackoverflow.com/questions/65351/null-or-default-comparsion-of-generic-argument-in-c-sharp – nawfal 2013-04-15 10:28:53

回答

53

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

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

这支持实现IEquatable<T>任何T,使用object.Equals作为备份,并处理null等等(并且自动解除运营商对于Nullable<T>)。

还有Comparer<T>.Default它处理比较测试。这处理T实施IComparable<T>,回落到IComparable - 再次处理null和解除运营商。

+0

你是说'EqualityComparer .Default.Equals'比Object.Equals'有更好的性能,或者它在某些情况下会给出正确的值,而Object.Equals不会呢? – Greg 2009-12-13 22:57:47

+9

更好的表现(减少拳击);考虑'T = int';调用'object.Equals'它必须包含'value'和'default(T)' - 这是两个额外的堆分配+ GC。使用'EqualityComparer '它有3个不同的底层实现 - 'class','Nullable '和'struct' - 它可以在没有**任何**装箱的情况下执行所有操作(包括'null'测试)。确定要使用哪种实现的工作只能针对每种类型和缓存执行一次,所以仍然非常快。 – 2009-12-13 23:27:38

+0

谢谢,Marc!你的解释很棒 – Greg 2009-12-14 00:07:33

21

什么

object.Equals(value, default(T)) 
+0

我知道它应该很简单。谢谢。 – Greg 2009-12-13 06:46:04

+1

+1。测试。适用于各种类型:'MyMethod(0); MyMethod (null); MyMethod (null);' - 在每种情况下返回true。 – 2009-12-13 09:25:11