2011-03-05 87 views
0

考慮這一點無可否認人爲的一般定義:什麼「where」子句將使這種通用方法起作用?

private void Foo<T,BASETYPE>(PropertyInfo prop, BASETYPE o1, BASETYPE o2) 
    { 
     T value1 = (T) prop.GetValue(o1, null); 
     T value2 = (T) prop.GetValue(o2, null); 
     if (value1 != value2) 
      Console.WriteLine("NOT EQUAL"); 
    } 

道具是保證爲BASETYPE一個的PropertyInfo。

我在if()語句得到一個編譯錯誤:

Operator '!=' cannot be applied to operands of type 'T' and 'T' 

而在「一般情況下,」據我所知,該錯誤信息是有效的,在這種情況下,我只希望在常規一些標準類型:System.Int64,System.String等全部支持==和!=運算符。

我認爲這可以用「where」子句修復,但IComparable和IEqualable不起作用。

有誰知道正確的「where」子句是什麼?

弗蘭克

回答

4

由於System.Int64,System.String,等等。從列表中實現IComparable,你可以使用

where T : IComparable 

,並使用CompareTo()代替!=

對於如。這段代碼編譯

private void Foo<T>(object o) where T : IComparable 
{ 
    T v1 = default(T); 
    T v2 = default(T); 
    if(v1.CompareTo(v2) != 0) 
    { 
     Console.WriteLine("Not Equal"); 
    } 
} 

private void Bar() 
{ 
    Foo<string>(new object()); 
} 
+0

這是比代碼需要更加具體。 'IEquatable'是你所需要的。 – luqui 2011-03-05 01:30:20

+0

當你真的不需要IComparable的排序功能時,這看起來像是對該類型的不必要的限制。 – 2011-03-05 01:31:44

+0

@Matt @luqui - 兩個界面都不限制你的選擇嗎?我認爲你們都同意IEquatable用於比較,IComparable用於排序。如果你的類型實現了一個,而不是另一個,你最終過濾可用的對象,不管是什麼? – 2011-03-05 01:35:37

0

不幸的是,我不認爲有一個。您需要使用.Equals()

0

可以使用Equals()實例方法,所有類型都有,靜態Object.ReferenceEquals()Object.Equals()方法,或者你可以使用EqualityComparer<T>.Default.Equals()方法。

0

如果你願意接受的性能損失,則可以使用

if (Comparer<T>.Default.Compare(value1, value2) == 0)) 
{ 
    Console.WriteLine("NOT EQUAL"); 
} 
+0

這很有趣。我以前從來沒有見過。是什麼導致性能下降?爲什麼不使用object.Equals? – 2011-03-05 01:26:51

0

我不認爲你可以。沒有操作符約束這樣的事情,所以沒有辦法告訴編譯器它應該只允許帶有!=操作符的對象被調用。您可以使用.Equals方法,因爲它在基礎對象類中。

這裏有一篇文章討論了運營商的限制: Operator Constraints