LINQ зависимое назначение расчета - PullRequest
4 голосов
/ 09 февраля 2009

Я использую следующий шаблон в 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 ]

8 голосов
/ 09 февраля 2009

Если вы развернете это для использования полного синтаксиса 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 () являются дорогостоящими операциями и необязательное выполнение их дважды может повлиять на производительность.

5 голосов
/ 09 февраля 2009

Вы не можете повторно использовать инициализированные свойства в инициализаторе.

Мне нравится техника Эрика. Если синтаксис выражения запроса мешает, вы можете использовать полный анонимный метод.

        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 };
            });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...