LINQ依赖计算分配

时间:2009-02-09 20:40:48

标签: c# linq extension-methods design-patterns

我在C#中使用以下模式:

IList<foo> x = y.Select(a => new foo
{
    b = Calc1(),
    c = Calc2()
}).ToList();

foreach(foo f in x)
{
    f.d = b / c;
}

我想做的是:

IList<foo> x = y.Select(a => new foo
{
    b = Calc1(),
    c = Calc2()
    d = b / c;
}).ToList();

所以问题是:如何修改此模式以允许赋值取决于在赋值期间计算的其他值?

(有人可能会指出d应该是进行计算的属性并返回一个值。这是一个人为的例子。假设d的值是使用除c和b之外的其他值计算的以后不可用。)

2 个答案:

答案 0 :(得分:8)

如果展开它以使用完整的LINQ语法:

IList<foo> x = (from a in y
                let bq = Calc1()
                let cq = Calc2()
                select new foo {
                    b = bq,
                    c = cq, 
                    d = bq / cq
                }).ToList();

这样可以得到你想要的东西。

有一个答案建议你重复你的方法调用(即,d = Calc1()/ Calc2()) - 但我建议不要这样做,考虑到Calc1()和Calc2()可能是昂贵的操作并且不必要地执行它们两次可能会对性能产生影响。

答案 1 :(得分:5)

您无法在初始化程序中重复使用初始化属性。

我喜欢Erik的技巧。如果查询表达式语法很麻烦,您可以使用全开匿名方法。

        List<int> y = new List<int>() { 1, 2, 3, 4 };
        var x = y.Select(a =>
            {
                int b = a + 1;
                int c = a + 2;
                int d = b / c;
                return new { b = b, c = c, d = d };
            });