Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Abfrageausdrücke
Abfrageausdrücke verwenden eine deklarative Syntax, die SQL oder XQuery ähnelt, um Sammlungen abzufragen System.Collections.Generic.IEnumerable<T> . Zur Kompilierzeit wird die Abfragesyntax in Methodenaufrufe in eine Implementierung des LINQ-Anbieters der Standardabfragemethoden konvertiert. Anwendungen steuern die Standardabfrageoperatoren, die sich im Geltungsbereich befinden, indem sie den entsprechenden Namespace mit einer using
Anweisung angeben. Der folgende Abfrageausdruck verwendet ein Array von Zeichenfolgen, gruppiert sie entsprechend dem ersten Zeichen in der Zeichenfolge und sortiert die Gruppen.
var query = from str in stringArray
group str by str[0] into stringGroup
orderby stringGroup.Key
select stringGroup;
Implizit typierte Variablen (var)
Sie können den Variablenmodifizierer verwenden, um den Compiler anzuweisen, den Typ zu ableiten und zuzuweisen, wie hier gezeigt:
var number = 5;
var name = "Virginia";
var query = from str in stringArray
where str[0] == 'm'
select str;
Variablen, die als var
deklariert werden, sind stark typisiert, genauso wie Variablen, deren Typ Sie explizit spezifizieren. Die Verwendung ermöglicht das Erstellen anonymer var
Typen, jedoch nur für lokale Variablen. Weitere Informationen finden Sie unter Implizit typierten lokalen Variablen.
Objekt- und Auflistungsinitialisierer
Objekt- und Auflistungsinitialisierer ermöglichen das Initialisieren von Objekten, ohne explizit einen Konstruktor für das Objekt aufzurufen. Initialisierer werden in der Regel in Abfrageausdrücken verwendet, wenn sie die Quelldaten in einen neuen Datentyp projizieren. Wenn eine Klasse namens Customer
mit öffentlichen Name
- und Phone
-Eigenschaften erstellt wird, kann der Objektinitialisierer wie im folgenden Code verwendet werden:
var cust = new Customer { Name = "Mike", Phone = "555-1212" };
Wenn Sie mit Ihrem Customer
Kurs fortfahren, nehmen Sie an, dass es eine Datenquelle namens IncomingOrders
gibt, und dass Sie für jede Bestellung mit einem großen OrderSize
ein neues Customer
basierend auf dieser Bestellung erstellen möchten. Eine LINQ-Abfrage kann für diese Datenquelle ausgeführt werden und die Objektinitialisierung verwenden, um eine Auflistung auszufüllen:
var newLargeOrderCustomers = from o in IncomingOrders
where o.OrderSize > 5
select new Customer { Name = o.Name, Phone = o.Phone };
Die Datenquelle hat möglicherweise mehr Eigenschaften definiert als die Customer
Klasse, beispielsweise OrderSize
. Aber mit der Objektinitialisierung werden die Daten aus der Abfrage in den gewünschten Datentyp umgewandelt. Sie wählen dann die Daten aus, die für Ihre Klasse relevant sind. Daher verfügen Sie jetzt über ein System.Collections.Generic.IEnumerable<T>-Element, das mit den neuen gewünschten Customer
-Informationen gefüllt ist. Das vorangehende Beispiel kann auch in der Methodensyntax von LINQ geschrieben werden:
var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });
Ab C# 12 können Sie einen Sammlungsausdruck verwenden, um eine Auflistung zu initialisieren.
Weitere Informationen finden Sie unter:
Anonyme Typen
Der Compiler erstellt einen anonymen Typ. Der Typname ist nur für den Compiler verfügbar. Anonyme Typen bieten eine bequeme Möglichkeit, einen Satz von Eigenschaften vorübergehend in einem Abfrageergebnis zu gruppieren, ohne einen separaten benannten Typ definieren zu müssen. Anonyme Typen werden mit einem neuen Ausdruck und einem Objektinitialisierer initialisiert, wie hier gezeigt:
select new {name = cust.Name, phone = cust.Phone};
Ab C# 7 können Sie Tupel verwenden, um unbenannte Typen zu erstellen.
Erweiterungsmethoden
Eine Erweiterungsmethode ist eine statische Methode, die einem Typ zugeordnet werden kann, sodass sie aufgerufen werden kann, als ob es sich um eine Instanzmethode für den Typ handelt. Mit dieser Funktion können Sie gewissermaßen neue Methoden zu vorhandenen Typen hinzufügen, ohne diese tatsächlich zu verändern. Die Standardabfrageoperatoren sind eine Reihe von Erweiterungsmethoden, die LINQ-Abfragefunktionen für jeden Typ bereitstellen, der IEnumerable<T> implementiert.
Lambda-Ausdrücke
Ein Lambdaausdruck ist eine Inlinefunktion, die den Operator =>
verwendet, um Eingabeparameter vom Funktionstext zu trennen, und die zur Kompilierzeit in einen Delegaten oder eine Ausdrucksbaumstruktur konvertiert werden kann. Bei der LINQ-Programmierung treten Lambda-Ausdrücke auf, wenn Sie direkte Methodenaufrufe an die Standardabfrageoperatoren ausführen.
Ausdrücke als Daten
Abfrageobjekte können verfasst werden, was bedeutet, dass Sie eine Abfrage aus einer Methode zurückgeben können. Objekte, die Abfragen darstellen, speichern nicht die resultierende Auflistung, sondern die Schritte, um die Ergebnisse bei Bedarf zu erzeugen. Der Vorteil der Rückgabe von Abfrageobjekten aus Methoden besteht darin, dass sie weiter zusammengesetzt oder geändert werden können. Daher muss jeder Rückgabewert oder out
Parameter einer Methode, die eine Abfrage zurückgibt, diesen Typ aufweisen. Wenn eine Methode eine Abfrage in einen konkreten List<T> Oder Array Typ materialisiert, gibt sie die Abfrageergebnisse anstelle der Abfrage selbst zurück. Eine Abfragevariable, die von einer Methode zurückgegeben wird, kann trotzdem verfasst oder geändert werden.
Im folgenden Beispiel gibt die erste Methode QueryMethod1
eine Abfrage als Rückgabewert zurück, und die zweite Methode QueryMethod2
gibt eine Abfrage als out
Parameter (returnQ
im Beispiel) zurück. In beiden Fällen handelt es sich um eine zurückgegebene Abfrage, nicht um Abfrageergebnisse.
IEnumerable<string> QueryMethod1(int[] ints) =>
from i in ints
where i > 4
select i.ToString();
void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
returnQ = from i in ints
where i < 4
select i.ToString();
int[] nums = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
var myQuery1 = QueryMethod1(nums);
Abfrage myQuery1
wird in der folgenden For-Each-Schleife ausgeführt.
foreach (var s in myQuery1)
{
Console.WriteLine(s);
}
Positionieren Sie den Mauszeiger über myQuery1
, um den Typ anzuzeigen.
Sie können auch die direkt von QueryMethod1
zurückgegebene Abfrage ausführen, ohne myQuery1
zu verwenden.
foreach (var s in QueryMethod1(nums))
{
Console.WriteLine(s);
}
Positionieren Sie den Mauszeiger über dem Aufruf an QueryMethod1
, um den Rückgabetyp anzuzeigen.
QueryMethod2
gibt eine Abfrage als Wert des out
Parameters zurück:
QueryMethod2(nums, out IEnumerable<string> myQuery2);
// Execute the returned query.
foreach (var s in myQuery2)
{
Console.WriteLine(s);
}
Sie können eine Abfrage mithilfe der Abfragekomposition ändern. In diesem Fall wird das vorherige Abfrageobjekt verwendet, um ein neues Abfrageobjekt zu erstellen. Dieses neue Objekt gibt unterschiedliche Ergebnisse als das ursprüngliche Abfrageobjekt zurück.
myQuery1 = from item in myQuery1
orderby item descending
select item;
// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
Console.WriteLine(s);
}