none
Average()を認識せず、エラーになってしまいます RRS feed

  • 質問

  • 開発環境

    VS2008 SP1

    コード

    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using System.Collections.Generic;
    using System.Linq;
    
    UInt32[] values = new UInt32[256];   // 元データが、カウンタの値として配列に予め入っている
    decimal val;
    
    val = values.Take(10 + 1).Average();  // エラーになってしまいます

    エラー表示は、次の通りです。

    エラー 1 'System.Collections.Generic.IEnumerable<uint>' に 'Average' の定義が含まれておらず、最も適している拡張メソッド オーバーロード 'System.Linq.Enumerable.Average(System.Collections.Generic.IEnumerable<decimal?>)' には無効な引数がいくつか含まれています

    何がいけなかったのでしょうか?

    何卒、ご教示下さい。

    2011年6月16日 9:06

回答

  • おのでらさんも挙げられていますMSDNのEnumerable.Average メソッド を読んでください。
    Averageの計算対象の型によって結果の型は変わるため、valの型を明示するなら戻り値の型に一致させておく必要があります。
    事前に型がわかりにくい場合はとりあえず、varで受けておけば楽です。

    たとえばInt64にキャストして計算させると結果はdoubleになります。
    var valInt64 = values.Take(10 + 1).Average((x) => (Int64)x);
    System.Diagnostics.Debug.WriteLine("Int64 : " + valInt64.GetType().Name);
    
    var valDouble = values.Take(10 + 1).Average((x) => (double)x);
    System.Diagnostics.Debug.WriteLine("Double : " + valDouble.GetType().Name);
    
    var valDecimal= values.Take(10 + 1).Average((x) => (Decimal)x);
    System.Diagnostics.Debug.WriteLine("Decimal : " + valDecimal.GetType().Name);
    
    
    • 回答としてマーク taokato 2011年6月17日 3:48
    2011年6月17日 3:35

すべての返信

  • Enumerable.Average メソッド (http://msdn.microsoft.com/ja-jp/library/system.linq.enumerable.average.aspx)を見る限りですと使用できる型は「Decimal」「Int32」「Int64」「Double」「Short」の5つだけっぽいので、一度これらの型の配列に変換しないと使えないかもしれないですね。

    UInt32 なら Int64 の配列にいれるとか。

     

    [追記]

    あとで思ったけど平均値なら力技でも十分に計算できるかなーとも思ったり。


    おのでら (http://sorceryforce.com/)

     


    2011年6月16日 9:27
  • 簡単にやるなら

    var val = values.Take(10+1).Average( (x) => (Int64)x );
    
    のようにInt64にキャストして計算させるとか。
    (キャストする型はdecimalでもdoubleでも。)
    2011年6月16日 10:00
  • gekkaさん 御返事有難うございます。

    やってみたら、次のようなエラーが出ます。

    「エラー 1 型 'double' を 'decimal' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください) 」

    decimal val;  を 'double' に変えても同じでした。

    キャストしているはずなのに、どうなっているんだろう?

    2011年6月17日 0:41
  • おのでらさんも挙げられていますMSDNのEnumerable.Average メソッド を読んでください。
    Averageの計算対象の型によって結果の型は変わるため、valの型を明示するなら戻り値の型に一致させておく必要があります。
    事前に型がわかりにくい場合はとりあえず、varで受けておけば楽です。

    たとえばInt64にキャストして計算させると結果はdoubleになります。
    var valInt64 = values.Take(10 + 1).Average((x) => (Int64)x);
    System.Diagnostics.Debug.WriteLine("Int64 : " + valInt64.GetType().Name);
    
    var valDouble = values.Take(10 + 1).Average((x) => (double)x);
    System.Diagnostics.Debug.WriteLine("Double : " + valDouble.GetType().Name);
    
    var valDecimal= values.Take(10 + 1).Average((x) => (Decimal)x);
    System.Diagnostics.Debug.WriteLine("Decimal : " + valDecimal.GetType().Name);
    
    
    • 回答としてマーク taokato 2011年6月17日 3:48
    2011年6月17日 3:35