Relaties typen in LINQ-querybewerkingen (C#)
Als u query's effectief wilt schrijven, moet u begrijpen hoe typen variabelen in een volledige querybewerking allemaal met elkaar te maken hebben. Als u deze relaties begrijpt, begrijpt u de LINQ-voorbeelden en codevoorbeelden in de documentatie gemakkelijker. Bovendien begrijpt u wat er gebeurt wanneer variabelen impliciet worden getypt met behulp van var
.
LINQ-querybewerkingen worden sterk getypt in de gegevensbron, in de query zelf en in de queryuitvoering. Het type variabelen in de query moet compatibel zijn met het type elementen in de gegevensbron en met het type iteratievariabele in de foreach
instructie. Deze sterke typen garanderen dat typefouten worden opgevangen tijdens het compileren wanneer ze kunnen worden gecorrigeerd voordat gebruikers ze tegenkomen.
Om deze typerelaties te demonstreren, gebruiken de meeste voorbeelden die expliciet typen volgen voor alle variabelen. In het laatste voorbeeld ziet u hoe dezelfde principes van toepassing zijn, zelfs wanneer u impliciet typen gebruikt met behulp van var
.
Query's die de brongegevens niet transformeren
In de volgende afbeelding ziet u een LINQ naar objectenquerybewerking die geen transformaties uitvoert op de gegevens. De bron bevat een reeks tekenreeksen en de queryuitvoer is ook een reeks tekenreeksen.
- Het typeargument van de gegevensbron bepaalt het type bereikvariabele.
- Het type object dat is geselecteerd, bepaalt het type van de queryvariabele. Hier
name
volgt een tekenreeks. Daarom is de queryvariabele eenIEnumerable<string>
. - De queryvariabele wordt in de
foreach
instructie overschreven. Omdat de queryvariabele een reeks tekenreeksen is, is de iteratievariabele ook een tekenreeks.
Query's die de brongegevens transformeren
In de volgende afbeelding ziet u een LINQ naar SQL-querybewerking waarmee een eenvoudige transformatie op de gegevens wordt uitgevoerd. De query gebruikt een reeks Customer
objecten als invoer en selecteert alleen de Name
eigenschap in het resultaat. Omdat Name
dit een tekenreeks is, produceert de query een reeks tekenreeksen als uitvoer.
- Het typeargument van de gegevensbron bepaalt het type bereikvariabele.
- De
select
instructie retourneert deName
eigenschap in plaats van het volledigeCustomer
object. OmdatName
het een tekenreeks is, is het typeargumentcustNameQuery
nietstring
Customer
. - Omdat
custNameQuery
dit een reeks tekenreeksen is, moet de herhalingsvariabele van deforeach
lus ook eenstring
.
In de volgende afbeelding ziet u een iets complexere transformatie. De select
instructie retourneert een anoniem type dat slechts twee leden van het oorspronkelijke Customer
object vastlegt.
- Het typeargument van de gegevensbron is altijd het type bereikvariabele in de query.
- Omdat de
select
instructie een anoniem type produceert, moet de queryvariabele impliciet worden getypt met behulp vanvar
. - Omdat het type van de queryvariabele impliciet is, moet de iteratievariabele in de
foreach
lus ook impliciet zijn.
Gegevens van het type compiler afleiden
Hoewel u de typerelaties in een querybewerking moet begrijpen, hebt u de mogelijkheid om de compiler al het werk voor u te laten doen. De trefwoordvariabele kan worden gebruikt voor elke lokale variabele in een querybewerking. De volgende afbeelding is vergelijkbaar met voorbeeldnummer 2 dat eerder is besproken. De compiler levert echter het sterke type voor elke variabele in de querybewerking.
LINQ- en algemene typen (C#)
LINQ-query's zijn gebaseerd op algemene typen. U hebt geen diepgaande kennis van generics nodig voordat u query's kunt schrijven. Mogelijk wilt u echter twee basisconcepten begrijpen:
- Wanneer u een exemplaar van een algemene verzamelingsklasse maakt, zoals List<T>, vervangt u de 'T' door het type objecten dat in de lijst wordt opgeslagen. Een lijst met tekenreeksen wordt bijvoorbeeld uitgedrukt als
List<string>
, en een lijst metCustomer
objecten wordt uitgedrukt alsList<Customer>
. Een algemene lijst is sterk getypt en biedt veel voordelen ten opzichte van verzamelingen die hun elementen opslaan als Object. Als u probeert eenCustomer
aan eenList<string>
toe te voegen, krijgt u tijdens het compileren een foutmelding. Het is eenvoudig om algemene verzamelingen te gebruiken omdat u geen runtime-type-casting hoeft uit te voeren. - IEnumerable<T> is de interface waarmee algemene verzamelingsklassen kunnen worden geïnventariseerd met behulp van de
foreach
instructie. Algemene verzamelingsklassen ondersteunen IEnumerable<T> net als niet-algemene verzamelingsklassen, zoals ArrayList ondersteuning IEnumerable.
Zie Generics voor meer informatie over generics.
IEnumerable<T-variabelen> in LINQ-query's
LINQ-queryvariabelen worden getypt als IEnumerable<T> of een afgeleid type, zoals IQueryable<T>. Wanneer u een queryvariabele ziet die als is getypt IEnumerable<Customer>
, betekent dit alleen dat de query, wanneer deze wordt uitgevoerd, een reeks nul of meer Customer
objecten produceert.
IEnumerable<Customer> customerQuery =
from cust in customers
where cust.City == "London"
select cust;
foreach (Customer customer in customerQuery)
{
Console.WriteLine($"{customer.LastName}, {customer.FirstName}");
}
Algemene typedeclaraties door de compiler laten verwerken
Als u wilt, kunt u algemene syntaxis vermijden met behulp van het trefwoord var . Het var
trefwoord geeft de compiler de opdracht om het type van een queryvariabele af te stellen door te kijken naar de gegevensbron die is opgegeven in de from
component. In het volgende voorbeeld wordt dezelfde gecompileerde code geproduceerd als in het vorige voorbeeld:
var customerQuery2 =
from cust in customers
where cust.City == "London"
select cust;
foreach(var customer in customerQuery2)
{
Console.WriteLine($"{customer.LastName}, {customer.FirstName}");
}
Het var
trefwoord is handig wanneer het type variabele duidelijk is of wanneer het niet zo belangrijk is om expliciet geneste algemene typen op te geven, zoals typen die worden geproduceerd door groepsquery's. Over het algemeen raden we u aan dat als u gebruikt var
, u er zeker van bent dat uw code moeilijker kan worden gelezen door anderen. Zie Impliciet getypte lokale variabelen voor meer informatie.