10

double の配列を取得して標準偏差を返す非常に単純なプログラムをいじっています。この部分は機能しましたが、コードをより再利用可能にしたかったのです。メソッドが数値と見なされる任意の型のパラメーターを受け入れ、double 型をハードコーディングする代わりに標準偏差を返すことができるようにしたいと思います (このプログラムで最初に行ったように)。これについてどのように対処し、適切な用語は何ですか?

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

            }
        }
    }
4

6 に答える 6

7

次のようなものを使用できます。

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

10 進数に変換できない値が含まれている場合は例外がスローvaluesされますが、値が適切な型の場合は機能します。これは完全に理にかなっていると思います。

于 2013-04-16T19:38:05.847 に答える
5

残念ながら、すべての数値に対応する基本クラスはありません。これは、一般的なランタイム チェック メソッド、またはコンパイル時に安全なオーバーロード セットを使用して行うことができます。

一般的な方法:

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

    //...

    return (T)standardDeviation;
}

単一のジェネリック メソッドを使用する場合の問題は、型パラメーターに、型パラメーターを数値型のみに制限する型制約を設定できないことです。実行時に失敗することに頼る必要があります。文字列、オブジェクト、Colors、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...
于 2013-04-16T19:27:57.317 に答える
0

数値の IEnumerable をパラメーターとしてメソッドに渡すことは、C# 6.0 でサポートされます。

于 2014-12-05T19:24:10.870 に答える
0

EDIT JLRisheの回答を使用する必要があります。これよりもはるかにエレガントです。

メソッドにジェネリックを追加することから始めて、型コンバーターを使用して不明な入力を次のように double に変換する必要があります。

public static double CalculateStandardDeviation<TSource>(IEnumerable<TSource> inputs)
{
    var converter = TypeDescriptor.GetConverter(typeof (double));
    if (!converter.CanConvertFrom(typeof(TSource)))
        return 0;

    var values = new List<double>();
    foreach (var value in inputs)
    {
        values.Add((double) converter.ConvertFrom(value));
    }

    // Your logic here ...
    return ...;
}

私はこのスニペットをテストしていませんが、アイデアはわかります。

于 2013-04-16T19:27:17.517 に答える