How to use a generic class for System.Math methods in C#
-
23-06-2021 - |
سؤال
I am trying to achieve something similar to the following code snippet.
As the red line indicates Math.Min
for IComparable<T>
does not seem to work. I need to use Math.Min
or Math.Max
for this generic class. The T
is going to be either int
or double
or decimal
type.
How could I easily solve this?
المحلول
Write your own generic Max
and Min
public static T Max<T>(T x, T y)
{
return (Comparer<T>.Default.Compare(x, y) > 0) ? x : y;
}
نصائح أخرى
There is no general solution for arithmetic operations. But for simple comparisons, you can trivially implement it yourself:
T Min<T>(T x1, T x2) where T:IComparable<T>
{
int comp=x1.CompareTo(x2);
if(comp<=0)
return x1;
else
return x2;
}
But I generally avoid the IComparable<T>
constraint, and rather ask the user to pass in IComparer<T>
as parameter to the constructor, and default to Comparer<T>.Default
if he doesn't specify one.
This technique allows using the class even on types that don't implement IComparable<T>
, provided the user passes in an alternative implementation.
class Foo<T>
{
readonly IComparer<T> _comparer;
public Foo()
:this(Comparer<T>.Default)
{
}
public Foo(IComparer<T> comparer)
{
_comparer=comparer;
}
T Min(T x1, T x2)
{
int comp = _comparer.Compare(x1,x2);
if(comp <= 0)
return x1;
else
return x2;
}
}
Ok, so it's going to be an int, decimal or double, so the ugly hack is to do something like
if not null
if(decimal.tryparse(val.ToString(), out aDecimal))
and if the other value can be made into a decimal
return math.max or min or what ever.
I'm already regretting using pseudo code...
Depending on what numerical types you include you just use the largest of them for the check above.
Be careful though as soon as someone says, "Hey this class is generic, lets use it with a class that wraps a decimal" you end up in a world of pain and then it's time to look at some of the other options posted here.