在Linq查询中执行代码块的语法?

时间:2013-05-09 16:37:39

标签: c# linq

这里有一些(显然)无法编译的代码:

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,具体取决于SomeField的值。我不能使用Func<>(或者我可以?),因为输入类型是匿名的。那么使这个工作的正确语法是什么?

3 个答案:

答案 0 :(得分:12)

首先,我通常更喜欢方法链语法而不是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。但是,我发现一旦你需要开始传递匿名类型,最好做一个实际的类。

答案 1 :(得分:8)

您可以将匿名函数包装为(自执行)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;
                    }
                  } )()
    };

答案 2 :(得分: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)
                        };