2009-02-09 4 views
4

Я использую следующий шаблон в C#:LINQ назначение зависит расчет

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, которые являются не доступен позже)

ответ

5

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

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

 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 }; 
      }); 
+0

Хороший пример, показывающий синтаксис метода расширения - +1 =) –

+0

Спасибо Дэвиду - очень изящный. – Guy

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

+0

Очень крутое решение и так же хорошо, как и у Дэвида +1. Я обозначил Дэвида как правильное решение, потому что он использовал синтаксис расширения, который я искал, но если бы я мог отметить оба правильных, я бы тоже отметил это. Спасибо за помощь Эрик! – Guy

+0

Не беспокойтесь =) Рад помочь. –