这里有一些(显然)无法编译的代码:
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<>
(或者我可以?),因为输入类型是匿名的。那么使这个工作的正确语法是什么?
答案 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)
};