如何在C#中使用通用类来调用System.Math方法

3

我正在尝试实现类似以下代码片段的功能。

enter image description here

正如红线所示,IComparable<T>Math.Min 似乎不起作用。我需要在这个通用类中使用 Math.MinMath.Max。其中 T 可以是 intdoubledecimal 类型。

我该如何轻松解决这个问题呢?


2
请不要发布文本截屏,请直接包含文本! - Jeff Mercado
3个回答

3

编写自己的通用 MaxMin

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

2

没有通用的算术操作解决方案。但对于简单的比较,您可以轻松地自己实现:

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;
  }
}

0

好的,那么它将是一个整数、十进制或双精度浮点数,所以丑陋的解决方法就是做类似于以下的事情

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.

我已经后悔使用伪代码了...

根据你包含的数字类型,只需使用其中最大的一个进行上述检查。

但要小心,一旦有人说:“嘿,这个类是通用的,让我们将其与一个包装十进制数的类一起使用”,你就会陷入痛苦之中,然后就是时候看看这里发布的其他选项了。


你需要一个条件调整来针对最后的二维数组赋值,具体取决于类型。研究一下 Convert 类,那会有所帮助。 - Ian
你的代码只有在某些 double 值下失败,因为 double 允许不同的值集合(特别是大的有限值、NaN 和无穷大)。 - CodesInChaos
完全同意,但对于大多数应用程序而言,NaN和无穷大并不是问题。我试图给出一个符合他最初要求的例子。我主要在金融领域工作。我相信我们的量化分析师正在努力寻找一种交易NaN的方法,从而获得无限的利润并取得胜利。但在那之前,我们只能处理实数 :) - Ian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接