2

除了我的问题

https://stackoverflow.com/questions/10241345/any-percentage-function-in-net

https://stackoverflow.com/questions/9942202/percentage-of-each-element-in-linq

我想在 .Net 4.0 中创建一个通用扩展方法,它将生成列表项占列表总和的百分比。此列表将仅为数字类型。

我的代码是

public static T Percentage<T>(this T array) where T: ? // What should come in place of ? 
{
  double[] darray = (double[])T; // Error convert type 'T' to 'double[]'

  darray = darray.Select(x=> x * 100 / darray.Sum()).ToArray();

  return darray; // Error convert type 'double[]' to 'T'
}

我想这样称呼它

double[] MD = {8.0,21.0,25.0,13.0,26.0,37.0,37.0,33.0,71.0,9.0};

MD = MD.Percentage().ToArray(); 

我究竟做错了什么;

4

3 回答 3

4

不可能有你想要的类型的约束。查看将泛型类型参数约束到数字类型以了解详细信息。

由于没有太多数字类型(int/float/double/decimal),因此简单地提供具体实现可能更容易。

更多的选择

于 2012-04-21T07:04:49.233 回答
4

您不能通过“数字”值来限制类型。这在某种程度上是框架的限制。

你最好的办法是这样做:

public static IEnumerable<double> Percentage(this IEnumerable<int> values)
{
    var sum = values.Sum();
    return values.Select(v => (double)v / (double)sum).ToArray();
}

public static IEnumerable<double> Percentage(this IEnumerable<long> values)
{
    var sum = values.Sum();
    return values.Select(v => (double)v / (double)sum).ToArray();
}

public static IEnumerable<double> Percentage(this IEnumerable<double> values)
{
    var sum = values.Sum();
    return values.Select(v => v / sum).ToArray();
}

本质上,您需要为要支持的每种类型生成一个重载。

于 2012-04-21T07:08:28.463 回答
1

还有另一种可行的方法,即传入选择器函数,该函数允许您在调用 Percentage 时转换为双精度值。这是扩展方法:

public static double[] Percentage<T>(this T[] array, Func<T,double> selector)
{
    var doubles = array.Select(selector);
    var sum = doubles.Sum();

    var result = doubles.Select(x => x * 100 / sum).ToArray();

    return result;
}

用法:

    double[] MD = {8.0,21.0,25.0,13.0,26.0,37.0,37.0,33.0,71.0,9.0};
var MDPercent = MD.Percentage(x => x).ToArray();

然后你可以有一个简单的双重版本:

public static double[] Percentage(this double[] array)
{
    return Percentage(array, x => x);
}

或一个 int 版本:

public static double[] Percentage(this int[] array)
{
    return array.Percentage(x => (double)x);
}

哪些更易于使用:

var MDPercent = MD.Percentage().ToArray();
于 2012-04-21T07:12:30.577 回答