Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare values of generic types?

How do I compare values of generic types?

I have reduced it to a minimal sample:

public class Foo<T> where T : IComparable {     private T _minimumValue = default(T);      public bool IsInRange(T value)      {         return (value >= _minimumValue); // <-- Error here     } } 

The error is:

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

What on earth!? T is already constrained to IComparable, and even when constraining it to value types (where T: struct), we still can't apply any of the operators <, >, <=, >=, == or !=. (I know that workarounds involving Equals() exist for == and !=, but it doesn't help for the relational operators).

So, two questions:

  1. Why do we observe this weird behaviour? What keeps us from comparing the values of generic types which are known to be IComparable? Doesn't it somehow defeat the entire purpose of generic constraints?
  2. How do I resolve this, or at least work around it?

(I realize there are already a handful of questions related to this seemingly simple problem - but none of the threads gives an exhaustive or workable answer, so here.)

like image 856
gstercken Avatar asked Jun 25 '11 21:06

gstercken


People also ask

How do I compare generic types in C#?

To enable two objects of a generic type parameter to be compared, they must implement the IComparable or IComparable<T>, and/or IEquatable<T> interfaces. Both versions of IComparable define the CompareTo() method and IEquatable<T> defines the Equals() method.

How do you compare type T?

If you need to compare objects of type T for equality/inequality, you can use the IEquatable<T> interface.

How do you find the type of generic type?

Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.


2 Answers

IComparable doesn't overload the >= operator. You should use

value.CompareTo(_minimumValue) >= 0 
like image 67
faester Avatar answered Sep 18 '22 13:09

faester


If value can be null the current answer could fail. Use something like this instead:

Comparer<T>.Default.Compare(value, _minimumValue) >= 0 
like image 38
Peter Hedberg Avatar answered Sep 18 '22 13:09

Peter Hedberg