C#-funktioner som stöder LINQ

Frågeuttryck

Frågeuttryck använder en deklarativ syntax som liknar SQL eller XQuery för att köra frågor mot System.Collections.Generic.IEnumerable<T> samlingar. Vid kompileringen konverteras frågesyntaxen till metodanrop till en LINQ-providers implementering av standardfrågemetoderna. Program styr de vanliga frågeoperatorer som finns i omfånget genom att ange lämpligt namnområde med ett using direktiv. Följande frågeuttryck tar en matris med strängar, grupperar dem enligt det första tecknet i strängen och beställer grupperna.

var query = from str in stringArray
            group str by str[0] into stringGroup
            orderby stringGroup.Key
            select stringGroup;

Implicit inskrivna variabler (var)

Du kan använda var-modifieraren för att instruera kompilatorn att härleda och tilldela typen, enligt följande:

var number = 5;
var name = "Virginia";
var query = from str in stringArray
            where str[0] == 'm'
            select str;

Variabler som deklareras som var är starkt inskrivna, precis som variabler vars typ du uttryckligen anger. Användningen av var gör det möjligt att skapa anonyma typer, men bara för lokala variabler. Mer information finns i Implicit inskrivna lokala variabler.

Initierare för objekt och samling

Initiatorer för objekt och samling gör det möjligt att initiera objekt utan att uttryckligen anropa en konstruktor för objektet. Initialiserare används vanligtvis i frågeuttryck när de projicerar källdata till en ny datatyp. Om vi antar en klass med namnet Customer med offentliga Name egenskaper och Phone egenskaper kan objektinitieraren användas som i följande kod:

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

Om du fortsätter med din Customer klass antar du att det finns en datakälla med namnet IncomingOrders, och att du för varje order med en stor OrderSize, vill skapa en ny Customer baserad av den ordern. En LINQ-fråga kan köras på den här datakällan och använda objektinitiering för att fylla en samling:

var newLargeOrderCustomers = from o in IncomingOrders
                            where o.OrderSize > 5
                            select new Customer { Name = o.Name, Phone = o.Phone };

Datakällan kan ha fler egenskaper definierade än Customer klassen, OrderSizetill exempel , men med objektinitiering formas data som returneras från frågan till önskad datatyp. Du väljer de data som är relevanta för din klass. Som ett resultat har du nu en System.Collections.Generic.IEnumerable<T> fylld med de nya Customers du ville ha. Föregående exempel kan också skrivas i LINQ:s metodsyntax:

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });

Från och med C# 12 kan du använda ett samlingsuttryck för att initiera en samling.

Mer information finns i:

Anonyma typer

Kompilatorn skapar en anonym typ. Typnamnet är endast tillgängligt för kompilatorn. Anonyma typer är ett bekvämt sätt att gruppera en uppsättning egenskaper tillfälligt i ett frågeresultat utan att behöva definiera en separat namngiven typ. Anonyma typer initieras med ett nytt uttryck och en objektinitierare, som du ser här:

select new {name = cust.Name, phone = cust.Phone};

Från och med C# 7 kan du använda tupplar för att skapa namnlösa typer.

Tilläggsmetoder

En tilläggsmetod är en statisk metod som kan associeras med en typ, så att den kan anropas som om det vore en instansmetod för typen. Med den här funktionen kan du i praktiken "lägga till" nya metoder i befintliga typer utan att ändra dem. Standardfrågeoperatorerna är en uppsättning tilläggsmetoder som tillhandahåller LINQ-frågefunktioner för alla typer som implementerar IEnumerable<T>.

Lambda-uttryck

Ett lambda-uttryck är en infogad funktion som använder operatorn => för att separera indataparametrar från funktionstexten och kan konverteras vid kompilering till ett ombud eller ett uttrycksträd. I LINQ-programmering får du lambda-uttryck när du gör direkta metodanrop till standardfrågeoperatorerna.

Uttryck som data

Frågeobjekt är skrivbara, vilket innebär att du kan returnera en fråga från en metod. Objekt som representerar frågor lagrar inte den resulterande samlingen, utan snarare stegen för att generera resultatet när det behövs. Fördelen med att returnera frågeobjekt från metoder är att de kan bestå eller ändras ytterligare. Därför måste ett returvärde eller out en parameter för en metod som returnerar en fråga också ha den typen. Om en metod materialiserar en fråga till en betong List<T> eller Array typ returneras frågeresultatet i stället för själva frågan. En frågevariabel som returneras från en metod kan fortfarande bestå eller ändras.

I följande exempel returnerar den första metoden QueryMethod1 en fråga som ett returvärde, och den andra metoden QueryMethod2 returnerar en fråga som en out parameter (returnQ i exemplet). I båda fallen är det en fråga som returneras, inte frågeresultat.

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);

Frågan myQuery1 körs i följande foreach-loop.

foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}

Vila muspekaren över myQuery1 för att se dess typ.

Du kan också köra frågan som returneras direkt QueryMethod1 , utan att använda myQuery1.

foreach (var s in QueryMethod1(nums))
{
    Console.WriteLine(s);
}

Vila muspekaren över anropet för att QueryMethod1 se dess returtyp.

QueryMethod2 returnerar en fråga som värdet för parametern out :

QueryMethod2(nums, out IEnumerable<string> myQuery2);

// Execute the returned query.
foreach (var s in myQuery2)
{
    Console.WriteLine(s);
}

Du kan ändra en fråga med hjälp av frågesammansättning. I det här fallet används det tidigare frågeobjektet för att skapa ett nytt frågeobjekt. Det här nya objektet returnerar andra resultat än det ursprungliga frågeobjektet.

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