2009-02-09 8 views
4

J'utilise le schéma suivant en C#:affectation de calcul dépendant LINQ

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

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

Ce que je voudrais faire bien est:

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

La question est la suivante: Comment pouvez-vous modifier cette pattern pour permettre l'attribution d'une valeur dépendant d'autres valeurs calculées pendant l'affectation?

(Quelqu'un indiquera probablement que d devrait être une propriété qui fait le calcul et renvoie une valeur.C'est un exemple inventé.Supposons que la valeur de d est calculée en utilisant d'autres valeurs en plus de c & b qui sont non disponible plus tard)

Répondre

5

Vous ne pouvez pas réutiliser les propriétés initialisées dans un initialiseur.

J'aime la technique d'Erik. Si la syntaxe de l'expression de la requête est dérangeante, vous pouvez utiliser une méthode anonyme complète.

 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

Bon exemple montrant la syntaxe de la méthode d'extension - +1 =) –

+0

Merci David - très élégant. – Guy

+0

Aucune méthode d'extension ici. : ~ –

8

Si vous développez cette option pour utiliser la syntaxe complète 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(); 

cela vous ce que vous voulez. Il y avait une réponse recommandant que vous répétiez vos appels de méthode (c.-à-d., D = Calc1()/Calc2()) - mais je recommanderais contre cela, considérant qu'il est possible que Calc1() et Calc2() soient chers opérations, et les effectuer inutilement deux fois peut avoir des implications sur les performances.

+0

Très bonne solution et aussi bonne que celle de David +1. J'ai choisi David comme étant la bonne solution parce que j'utilisais la syntaxe d'extension que je cherchais, mais si je pouvais marquer les deux comme corrects, je marquerais aussi celui-ci. Merci pour l'aide Erik! – Guy

+0

Pas de soucis =) Content d'avoir pu aider. –