我正在根据数据行创建一个对象数组,如下所示。在工作的时候,通过从行中的单元格中拉出相同的值,我做了一些操作,这让我感到困扰。通常,这个东西会在循环之前预先准备好,然后在这里设置多次但,我不会获得该值,直到在实际迭代中。
return table.Rows.Cast<DataRow>()
.Select(row => new Beep
{
Uno = HeavyComputation(row["ID"]),
Duo = HeavyComputation(row["ID"])
}).ToList();
能否以更好的方式解决这个问题?有点像(只是在这里做白日梦)吗?
return table.Rows.Cast<DataRow>()
.Preset("int preComputed = HeavyComputation(row['ID'])"
.Select(row => new Beep
{
Uno = preComputed,
Duo = preComputed
}).ToList();
请注意,实际示例有点复杂,上面的代码是问题的最小例证。我做认识到 Uno 和 Duo 在这里是多余的。 :)
答案 0 :(得分:5)
您可以这样做:
return table.Rows.Cast<DataRow>()
.Select(row => {
long preComputed = HeavyComputation(row["ID"]);
return new Beep
{
Uno = preComputed,
Duo = preComputed
};
});
在这种情况下,Select
的参数是Func<DataRow, Beep>
。由于Func<>
只是一个委托,因此您可以将匿名方法传递给Select
,如上例所示。你也可以这样做:
public Beep TransformToBeep(DataRow dr)
{
//Do a lot of work here
return new Beep { ... };
}
然后在你的Select
中写一下:
return table.Rows.Cast<DataRow>().Select(TransformToBeep).ToList();
答案 1 :(得分:4)
在查询表达式中,您可以使用let
:
return from DataRow row in table.Rows
let preComputed = HeavyComputation(row["ID"])
select new Beep
{
// Use row and preComputed here
};
要在非查询表达式中具有相同的效果,您可以使用多个Select
调用:
return table.Rows.Cast<DataRow>()
.Select(row => new { row, preComputed = HeavyComputation(row["ID"]) })
// Other stuff here if you want
.Select(pair => new Beep {
Uno = pair.preComputed,
Duo = pair.preComputed,
Trio = pair.Row[...]
});
如果您仅在最终preComputed
中需要Select
,则可以使用:
return table.Rows.Cast<DataRow>()
.Select(row => HeavyComputation(row["ID"]))
.Select(preComputed => new Beep {
Uno = preComputed,
Duo = preComputed
});
如果你很高兴有声明lambda(而不是表达lambdas),那么你当然可以使用Klaus的方法。请记住,虽然LINQ to SQL之类的东西不起作用,但它只适用于Enumerable
,语句lambdas无法转换为表达式树。