将IEnumerable数值作为参数传递给方法

woo*_*gie 9 c# visual-studio-2010

我正在玩一个非常简单的程序来获取一系列双打并返回标准偏差.这部分工作但我想让代码更可重用.我想这样做,所以该方法可以接受任何类型的参数,可以被认为是数字并返回标准偏差而不是硬编码双重类型(就像我最初在这个程序中做的那样).如何解决这个问题以及适当的术语是什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


    namespace ConsoleApplication5
    {
        class Program
        {
            static void Main(string[] args)
            {
                double[] avg = { 3.4, 55.6, 10.0, 4.5, 2, 2 };
                double x = avg.Average();
                //first round of testing
                Console.WriteLine("The average of the first array is below ");
                Console.WriteLine(x);
                Console.WriteLine("below should be the standard deviation!");
                Console.WriteLine(CalculateStandardDeviation(avg));
                Console.ReadLine();
                int[] intAvg = { 4, 3, 5, 6, 2 };
                double secondAvg = intAvg.Average();
                Console.WriteLine("The average of the second array is below ");
                Console.WriteLine(secondAvg);
                //this is where the error is happening
                //CalculateStandardDeviation(secondAvg);

            }
            //this is where I tried to make the query more reusable
            public static double CalculateStandardDeviation(IEnumerable<double> values)
            {

                double avg = values.Average();
                double sum = 0;
                foreach (double d in values)
                {
                    sum += Math.Pow((d - avg), 2);

                }

                return Math.Pow(sum / (values.Count() - 1),.5);

            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

JLR*_*she 6

你可以使用这样的东西:

public static decimal CalculateStandardDeviation<T>(IEnumerable<T> values)
{
    IEnumerable<decimal> decimalValues = values.Select(v => Convert.ToDecimal(v));

    decimal result = 0;

    // calculate standard deviation on decimalValues

    return result;
}
Run Code Online (Sandbox Code Playgroud)

如果values包含无法转换为小数的值,它将抛出异常,但如果值是合适的类型,它将起作用,我认为这是完全合理的.

  • 这是一个[lambda表达](http://msdn.microsoft.com/en-us/library/bb397687.aspx).当在'IEnumerable <T> .Select()`中使用时,它实质上意味着"take(`=>`左边的内容)并给我(`=>`右边的内容)". (2认同)

Dan*_*Dan 5

不幸的是,所有数字都没有基类.您可以使用通用运行时检查方法或编译时安全的重载集来执行此操作.

通用方法:

public static T CalculateStandardDeviation(IEnumerable<T> values)
{
    var valueArray = values.Select(Convert.ToDecimal).ToArray();

    //...

    return (T)standardDeviation;
}
Run Code Online (Sandbox Code Playgroud)

使用单个泛型方法的问题在于,您不能对类型参数设置类型约束,以将其限制为仅数字类型.你不得不求助于在运行时失败.没有什么可以阻止你用一个字符串,对象,颜色或HttpWebRequests等数组调用方法,除非你确实知道如何计算颜色的标准偏差,你应该坚持特定数字类型的单个覆盖:

我建议使用decimal类型作为主要实现,然后将所有内容都转换为它.

特定类型的重载:

public static decimal CalculateStandardDeviation(IEnumerable<decimal> values)
{
    //...
}

public static double CalculateStandardDeviation(IEnumerable<double> values)
{
    return (double)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}

public static int CalculateStandardDeviation(IEnumerable<int> values)
{
    return (int)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}

// etc...
Run Code Online (Sandbox Code Playgroud)

  • @Brian同意了,但是数字类型很少,所以我不认为这是一个很大的问题. (3认同)
  • 颜色的标准偏差:`Color.FromArgb(255 - CalculateStandardDeviation(colors.Select(c => cA)),CalculateStandardDeviation(colors.Select(c => cR)),CalculateStandardDeviation(colors.Select(c => cG)) ,CalculateStandardDeviation(colors.Select(c => cB)))`.类似的颜色将接近黑色和不透明. (2认同)
  • @Tim很好!现在我们可以为Colors添加重载!这对许多人来说非常有用,我敢肯定!:) (2认同)