我正在尝试实现类似以下代码片段的功能。
正如红线所示,IComparable<T>
的 Math.Min
似乎不起作用。我需要在这个通用类中使用 Math.Min
或 Math.Max
。其中 T
可以是 int
、double
或 decimal
类型。
我该如何轻松解决这个问题呢?
我正在尝试实现类似以下代码片段的功能。
正如红线所示,IComparable<T>
的 Math.Min
似乎不起作用。我需要在这个通用类中使用 Math.Min
或 Math.Max
。其中 T
可以是 int
、double
或 decimal
类型。
我该如何轻松解决这个问题呢?
编写自己的通用 Max
和 Min
public static T Max<T>(T x, T y)
{
return (Comparer<T>.Default.Compare(x, y) > 0) ? x : y;
}
没有通用的算术操作解决方案。但对于简单的比较,您可以轻松地自己实现:
T Min<T>(T x1, T x2) where T:IComparable<T>
{
int comp=x1.CompareTo(x2);
if(comp<=0)
return x1;
else
return x2;
}
但通常我会避免使用 IComparable<T>
的限制,而是要求用户将 IComparer<T>
作为构造函数的参数传入,并在用户没有指定时默认使用 Comparer<T>.Default
。
这种技术允许在不实现 IComparable<T>
接口的类型上使用该类,只要用户传入替代实现即可。
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;
}
}
好的,那么它将是一个整数、十进制或双精度浮点数,所以丑陋的解决方法就是做类似于以下的事情
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.
我已经后悔使用伪代码了...
根据你包含的数字类型,只需使用其中最大的一个进行上述检查。
但要小心,一旦有人说:“嘿,这个类是通用的,让我们将其与一个包装十进制数的类一起使用”,你就会陷入痛苦之中,然后就是时候看看这里发布的其他选项了。
double
值下失败,因为 double
允许不同的值集合(特别是大的有限值、NaN 和无穷大)。 - CodesInChaos