LINQ依赖计算分配

Guy*_*Guy 4 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;
}
Run Code Online (Sandbox Code Playgroud)

我想做的是:

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

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

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

Eri*_*bes 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();
Run Code Online (Sandbox Code Playgroud)

这将为您提供您想要的.

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


Amy*_*y B 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 };
            });
Run Code Online (Sandbox Code Playgroud)