2010-02-02 61 views
8

我希望能夠檢查某個值是否爲其值類型的默認值。理想情況下,我想說:使用泛型類型進行缺省值檢查

DoSomething<TValue>(TValue value) { 
    if (value == default(TValue)) { 
     ... 
    } 
} 

然而,編譯器抱怨說,它不能對TValue和TValue一個==比較。這是我想出來的迄今爲止最好的解決方法:

DoSomething<TValue>(TValue value) { 
    if (value == null || value.Equals(default(TValue))) { 
     ... 
    } 
} 

有沒有去這更優雅/正確的方法?

回答

37
public bool EqualsDefaultValue<T>(T value) 
{ 
    return EqualityComparer<T>.Default.Equals(value, default(T)); 
} 
4

拋出類約束,它應該工作。

public void Test<T>(T instance) where T : class 
{ 
    if (instance == default(T)) 
    { 

    } 
} 

或者,如果你只想要值類型,你可以做到這一點。

public void Test<T>(T instance) where T : struct, IEquatable<T> 
{ 
    if (instance.Equals(default(T))) 
    { 

    } 
} 
+4

如果你拋出''類'約束你可能只是檢查'null' ... – 2010-02-02 20:48:49

+0

@Marc - 我知道,在這一點上它是一個問題的偏好。 – ChaosPandion 2010-02-02 20:51:48

+0

我希望能夠爲任何類型的工作,包括價值和類的類型。 – StriplingWarrior 2010-02-02 21:02:27

1

您的問題是一個genric型(沒有限制)必須對任何類型的「編譯」。由於並非所有類型都有==運算符,因此您的代碼將無法編譯。

解決它的一種方法是添加類約束,但是因爲使用默認(TValue)會暗示您希望代碼與其他類型一起使用。 (否則只是使用空,而不是默認(TValue)。一種解決方案是類似於布賴恩·沃茨建議

bool DoSomething<TValue>(TValue value) { 
    return EqualityComparer<TValue>.Default.Equals(value, default(TValue)); 
} 

,或者你可以在一個擴展方法

bool IsDefault<TValue>(this TValue value) { 
    return EqualityComparer<TValue>.Default.Equals(value, default(TValue)); 
} 
0

添加到包起來的東西張貼在這裏的答案,我想我們也應該能夠指定是否我們想要的數值或引用平等:

static public class MyGenericHelper 
{ 
    static public bool EqualsByValue<T>(T x, T y) 
    { 
     return EqualityComparer<T>.Default.Equals(x, y); 
    } 

    static public bool EqualsByReference<T>(T x, T y) 
    { 
     if (x is ValueType) return EqualityComparer<T>.Default.Equals(x, y) // avoids boxing 

     return Object.ReferenceEquals(x, y); 
    } 
} 

我們都只是愛創造和維持一個小數不勝數的H ^像這樣的方法我們不: - >

+0

在可讀性和性能方面,似乎'typeof(T).IsValueType'優於'x是ValueType'。我錯了嗎? – StriplingWarrior 2010-02-02 22:23:10

+1

也許可讀性有時候是一種味道的問題。 : - > ...''x對於我來說直覺上「感覺更快」是因爲'typeof(T).IsValueType'必須檢索相當重的'Type'實例,並且Reflector顯示'.IsValueType'屬性調用一個在'RuntimeType'中實現的虛擬方法,最終調用extern。但是,我是誰來判斷,我不是內部人士。他們甚至可能會按照相同的說明進行編譯。也許這是一個很好的新問題。 ;-) ...或者你可以自己做一些性能測試,如果它是至關重要的。 – herzmeister 2010-02-02 23:18:41

+0

這並不重要,但我很好奇,所以我做了一個快速測試,你是對的! 'x是ValueType'大約需要三分之一的時間。 – StriplingWarrior 2010-02-03 17:29:08