2016-08-07 13 views
-1

Ich möchte den Nebeneffekt, wenn Lambda-Ausdruck mit Select Extension-Methode verwenden, etwa so:Wie kann ein Objekt aus einem Lambda-Ausdruckskörper in der Linq-Erweiterungsmethode geändert werden?

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace SyntaxExperiment { 

    public class Program { 
     static void Main() { 
      var list = new List<int>(); 
      var results = new[] { 1, 2, 3 } 
       .Select(
        i => { 
         list.Add(i); 
         return i; 
        } 
       ); 
      Console.WriteLine(list.Count); 
     } 
    } 
} 

Der obige Code Ausgänge:

0 

Wie ist das möglich?

Antwort

3

Der LINQ-Code wird nicht ausgeführt, weil es nur eine IEnumerable<int> ist, die keinen Grund zur Ausführung hat. Sie können ihn zwingen, wie dies auszuführen:

var results = new[] { 1, 2, 3 } 
    .Select(i => { 
     list.Add(i); 
     return i; 
    }) 
    .ToList(); 

Um es anders auszudrücken, ein enumerable nichts tun, bis Sie durch sie aufzählen und ToList, indem Sie die Daten in eine Sammlung zu zwingen, verursacht diese Aufzählung.

+2

Und die obligitory „Sie sollten sich nicht auf Nebenwirkungen werden zu zählen, wenn LINQ-Abfragen laufen, das ist nicht das, was es für entworfen wurde.“ –

1

LINQ basiert auf funktionalen Programmierprinzipien. Obwohl es möglich ist, ist es nicht wirklich darauf ausgelegt, Daten zu mutieren oder Dinge durch Nebeneffekte zu erledigen.

Was Sie tun möchten (vorausgesetzt, der echte Code ist komplizierter als Ihr Beispiel!) Wählen Sie die erforderlichen Daten und konvertieren Sie dann IEnumerable in eine Liste.

var results = new[] { 1, 2, 3 }.Select(i => i).ToList(); 
1

Sie können auch Foreach wie unter

verwenden
static void Main() 
{ 
    List<int> list = new List<int>(); 
    var results = new[] { 1, 2, 3 }; 
    results.ToList().ForEach(i => list.Add(i)); 
    Console.WriteLine(list.Count); 
} 
+0

ForEach ist eigentlich keine Erweiterungsmethode für IEnumerable/Teil von LINQ - im Einklang mit den Prinzipien der funktionalen Programmierung. Der Grund, dass Sie die .ToList() aufrufen müssen, ist, weil ForEach in der Liste ist. – brent