2011-03-05 31 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