15

(明らかに) コンパイルされないコードを次に示します。

var q = from x in myAnonymousTypeCollection
        select new {
          x.ID,
          CalcField = { 
                        switch(x.SomeField) {
                          case 1:
                            return Math.Sqrt(x.Field1);
                          case 2:
                            return Math.Pow(x.Field2, 2);
                          default:
                            return x.Field3;
                        }
                      }
        };

あなたは絵を手に入れます。CalcFieldの値に応じて、まったく異なる方法で計算しようとしていますSomeFieldFunc<>入力タイプが匿名であるため、a を使用できません(または使用できますか?)。では、これを機能させるための正しい構文は何ですか?

4

3 に答える 3

13

まず、私は通常、Linq のクエリ構文よりもメソッド チェーン構文を好みます。これを使えば簡単にできます。

var q = myAnonymousTypeCollection
    .Select(x => 
            {
                object calcField; 

                 switch(x.SomeField) 
                 {
                      case 1:
                        calcField = Math.Sqrt(x.Field1);
                      case 2:
                        calcField =  Math.Pow(x.Field2, 2);
                      default:
                        calcField = x.Field3;

                 return new 
                        {
                            x.ID,
                            CalcField = calcField
                        };
            });

メソッド チェーンを使用しない場合は、メソッドまたは Func が必要です。Funcを仮定しましょう

//replace these with actual types if you can.
Func<dynamic, dynamic> calculateField = 
    x => 
    {
        switch(x.SomeField) {
            case 1:
                return Math.Sqrt(x.Field1);
            case 2:
                return Math.Pow(x.Field2, 2);
            default:
                return x.Field3;
    }

var q = from x in myAnonymousTypeCollection
        select new { x.Id, CalcField = calculateField(x) };

注: これは IDE で書いたものではないので、単純なエラーはご容赦ください。

dynamicの MSDN は次のとおりです。ただし、匿名型を渡し始める必要がある場合は、実際のクラスを作成するのが最善であることがわかりました。

于 2013-05-09T16:46:35.727 に答える
9

匿名関数を (自己実行型の)Func<>デリゲートとしてラップできます。これは、戻り値の型を知っていることを前提としています。

var q = from x in myAnonymousTypeCollection
    select new {
      ID = x.ID,
      CalcField = new Func<double>( () => { 
                    switch(x.SomeField) {
                      case 1:
                        return Math.Sqrt(x.Field1);
                      case 2:
                        return Math.Pow(x.Field2, 2);
                      default:
                        return x.Field3;
                    }
                  } )()
    };
于 2013-05-09T16:47:00.973 に答える
1

次のように、スイッチ ロジックを別の関数に簡単に移動できます。

private static T GetReturnValue<T>(myClass x)
{
    switch (x)
    {
        case 1:
            return Math.Sqrt(x.Field1);
            break;
        case 2:
            return Math.Pow(x.Field2,
                            2);
            break;
        default:
            return x.Field3;
            break;
    }
}

そして、オブジェクトをその関数に渡して、必要な値を取得するだけです。

var q = from x in myAnonymousTypeCollection
                    select new
                        {
                            ID = x.ID,
                            CalcField = GetReturnValue(x)
                        };
于 2013-05-09T16:53:04.627 に答える