2009-12-13 102 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