Projektionsvorgänge

Aktualisiert: November 2007

Projektion bezeichnet einen Vorgang, bei dem ein Objekt in eine neue Form transformiert wird, die häufig nur aus den Eigenschaften besteht, die anschließend verwendet werden. Mithilfe der Projektion können Sie einen neuen Typ erstellen, der aus den einzelnen Objekten erstellt wird. Sie können eine Eigenschaft projizieren und eine mathematische Funktion dafür ausführen. Außerdem kann das ursprüngliche Objekt projiziert werden, ohne es zu ändern.

Die Standardabfrageoperator-Methoden, die die Projektion ausführen, werden im folgenden Abschnitt aufgelistet.

Methoden

Methodenname

Beschreibung

C#-Abfrageausdruckssyntax

Visual Basic-Abfrageausdruckssyntax

Weitere Informationen

Select

Projiziert Werte, die auf einer Transformationsfunktion basieren.

select

Select

Enumerable.Select

Queryable.Select

SelectMany

Projiziert Sequenzen von Werten, die auf einer Transformationsfunktion basieren, und fasst sie anschließend in einer Sequenz zusammen.

Verwendung mehrerer from-Klauseln

Verwendung mehrerer From-Klauseln

Enumerable.SelectMany

Queryable.SelectMany

Beispiele für Abfrageausdruckssyntax

Select

Im folgenden Beispiel wird die select-Klausel in C# oder die Select-Klausel in Visual Basic verwendet, um den ersten Buchstaben der einzelnen Zeichenfolgen aus einer Zeichenfolgenliste zu projizieren.

Dim words As New List(Of String)(New String() {"an", "apple", "a", "day"})

Dim query = From word In words _
            Select word.Substring(0, 1)

Dim sb As New System.Text.StringBuilder()
For Each letter As String In query
    sb.AppendLine(letter)
Next

' Display the output.
MsgBox(sb.ToString())

' This code produces the following output:

' a
' a
' a
' d

List<string> words = new List<string>() { "an", "apple", "a", "day" };

var query = from word in words
            select word.Substring(0, 1);

foreach (string s in query)
    Console.WriteLine(s);

/* This code produces the following output:

    a
    a
    a
    d
*/

SelectMany

Im folgenden Beispiel werden mehrere from-Klauseln in C# oder From -Klauseln in Visual Basic verwendet, um jedes Wort der einzelnen Zeichenfolgen aus einer Zeichenfolgenliste zu projizieren.

Dim phrases As New List(Of String)(New String() {"an apple a day", "the quick brown fox"})

Dim query = From phrase In phrases _
            From word In phrase.Split(" "c) _
            Select word

Dim sb As New System.Text.StringBuilder()
For Each str As String In query
    sb.AppendLine(str)
Next

' Display the output.
MsgBox(sb.ToString())

' This code produces the following output:

' an
' apple
' a
' day
' the
' quick
' brown
' fox

List<string> phrases = new List<string>() { "an apple a day", "the quick brown fox" };

var query = from phrase in phrases
            from word in phrase.Split(' ')
            select word;

foreach (string s in query)
    Console.WriteLine(s);

/* This code produces the following output:

    an
    apple
    a
    day
    the
    quick
    brown
    fox
*/

Select und SelectMany im Vergleich

Die Aufgabe sowohl von Select() als auch von SelectMany() besteht darin, einen oder mehrere Ergebniswerte aus Quellwerten zu generieren. Select() generiert einen Ergebniswert für jeden Quellwert. Daher entspricht das Gesamtergebnis einer Auflistung, die dieselbe Anzahl von Elementen wie die Quellauflistung aufweist. SelectMany() erzeugt im Gegensatz dazu ein einzelnes Gesamtergebnis, das verkettete Unterauflistungen von jedem Quellwert enthält. Die als Argument an SelectMany() übergebene Transformationsfunktion muss für jeden Quellwert eine Sequenz von Werten zurückgeben, die aufgelistet werden können. Diese auflistbaren Sequenzen werden dann durch SelectMany() zu einer großen Sequenz verkettet.

Die folgenden beiden Abbildungen zeigen den konzeptionellen Unterschied zwischen den Aktionen dieser beiden Methoden. In beiden Fällen wird davon ausgegangen, dass die Auswahlfunktion (Transformationsfunktion) das Blumenarrangement aus jedem Quellwert auswählt.

Aus der Abbildung ist ersichtlich, dass Select() eine Auflistung zurückgibt, die über dieselbe Anzahl von Elementen wie die Quellauflistung verfügt.

Konzeptionelle Darstellung der Aktion Select()

Diese Abbildung zeigt, wie die Zwischensequenz von Arrays von SelectMany() zu einem endgültigen Ergebniswert verkettet wird, der jeden Wert aus den einzelnen Zwischenarrays enthält.

Grafische Darstellung der Aktion SelectMany().

Codebeispiel

Im folgenden Beispiel wird das Verhalten von Select() und SelectMany() verglichen. Durch den Code wird ein "Strauß" aus Blumen gebildet, indem die ersten beiden Elemente aus jeder Liste mit Blumennamen in die Quellauflistung eingefügt werden. In diesem Beispiel entspricht der von der Transformationsfunktion Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>) verwendete "Einzelwert" selbst einer Werteauflistung. Die zusätzliche foreach-Schleife (For Each-Schleife in Visual Basic) ist erforderlich, damit jede Zeichenfolge in den einzelnen Untersequenzen aufgelistet wird.

Class Bouquet
    Public Flowers As List(Of String)
End Class

Sub SelectVsSelectMany()
    Dim bouquets As New List(Of Bouquet)(New Bouquet() { _
        New Bouquet With {.Flowers = New List(Of String)(New String() {"sunflower", "daisy", "daffodil", "larkspur"})}, _
        New Bouquet With {.Flowers = New List(Of String)(New String() {"tulip", "rose", "orchid"})}, _
        New Bouquet With {.Flowers = New List(Of String)(New String() {"gladiolis", "lily", "snapdragon", "aster", "protea"})}, _
        New Bouquet With {.Flowers = New List(Of String)(New String() {"larkspur", "lilac", "iris", "dahlia"})}})

    Dim output As New System.Text.StringBuilder

    ' Select()
    Dim query1 = bouquets.Select(Function(b) b.Flowers)

    output.AppendLine("Using Select():")
    For Each flowerList In query1
        For Each str As String In flowerList
            output.AppendLine(str)
        Next
    Next

    ' SelectMany()
    Dim query2 = bouquets.SelectMany(Function(b) b.Flowers)

    output.AppendLine(vbCrLf & "Using SelectMany():")
    For Each str As String In query2
        output.AppendLine(str)
    Next

    ' Display the output
    MsgBox(output.ToString())

    ' This code produces the following output:
    '
    ' Using Select():
    ' sunflower
    ' daisy
    ' daffodil
    ' larkspur
    ' tulip
    ' rose
    ' orchid
    ' gladiolis
    ' lily
    ' snapdragon
    ' aster
    ' protea
    ' larkspur
    ' lilac
    ' iris
    ' dahlia

    ' Using SelectMany()
    ' sunflower
    ' daisy
    ' daffodil
    ' larkspur
    ' tulip
    ' rose
    ' orchid
    ' gladiolis
    ' lily
    ' snapdragon
    ' aster
    ' protea
    ' larkspur
    ' lilac
    ' iris
    ' dahlia

End Sub
class Bouquet
{
    public List<string> Flowers { get; set; }
}

static void SelectVsSelectMany()
{
    List<Bouquet> bouquets = new List<Bouquet>() {
        new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }},
        new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }},
        new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }},
        new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }}
    };

    // *********** Select ***********            
    IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);

    // ********* SelectMany *********
    IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);

    Console.WriteLine("Results by using Select():");
    // Note the extra foreach loop here.
    foreach (IEnumerable<String> collection in query1)
        foreach (string item in collection)
            Console.WriteLine(item);

    Console.WriteLine("\nResults by using SelectMany():");
    foreach (string item in query2)
        Console.WriteLine(item);

    /* This code produces the following output:

       Results by using Select():
        sunflower
        daisy
        daffodil
        larkspur
        tulip
        rose
        orchid
        gladiolis
        lily
        snapdragon
        aster
        protea
        larkspur
        lilac
        iris
        dahlia

       Results by using SelectMany():
        sunflower
        daisy
        daffodil
        larkspur
        tulip
        rose
        orchid
        gladiolis
        lily
        snapdragon
        aster
        protea
        larkspur
        lilac
        iris
        dahlia
    */

}

Weitere Informationen zur Projektion

Siehe auch

Konzepte

Übersicht über Standardabfrageoperatoren

Referenz

select-Klausel (C#-Referenz)

Select-Klausel (Visual Basic)

System.Linq