tags:

views:

590

answers:

3

Hello.

I was thinking about writing generic functions for basic Math operations such as Min, Max etc. But i i dont know how to compare two generic types :

 public T Max<T>(T v1, T v2) where T: struct
 {
  return (v1 > v2 ? v1 : v2);
 }

How about that?

Thank you.

+15  A: 

You probably want to constrain the generic types to implement IComparable:

public T Max<T>(T v1, T v2) where T: struct, IComparable<T>

and then use the CompareTo method:

{
    return (v1.CompareTo(v2) > 0 ? v1 : v2);
}
Joey
Excellent, thank you.
Feryt
@Feryt:Note that there's no need to constrain it to `struct`s.
Dario
Well, the `struct` avoids the `null` problem, but IMO this is the wrong answer; Luke has the right of it.
Marc Gravell
A: 

From memory, T also needs to be IComparable (add that to the where), and then you use v1.CompareTo(v2) > 0 etc.

Will
+8  A: 

If you only want to create comparison functions then you could use the default comparer for the type T. For example:

public static T Max<T>(T x, T y)
{
    return (Comparer<T>.Default.Compare(x, y) > 0) ? x : y;
}

If T implements IComparable<T> then that comparer will be used; if T doesn't implement IComparable<T> but does implement IComparable then that comparer will be used; if T doesn't implement either IComparable<T> or IComparable then a runtime exception will be thrown.

If you want/need to do more than just compare the items then you could have a look at the generic operators implementation in MiscUtil and the related article.

LukeH
This is very elegant and generic solution. I like it too.
Feryt
This is the right answer, IMO. As an aside, a common alternative pattern is to have two overloads; one passes `Comparer<T>.Default` to the second, which accepts `IComparer<T>` (for the cases when you want to customise it). But for the simple case, this is the way to go.
Marc Gravell