BLOG

Achtergronden

Wat is er nieuw in C# 10?

21 juni 2021

Tijdens de jaarlijkse Build Conferentie heeft Microsoft inzicht gegeven in de ontwikkelingen rondom C# en .Net 6. In November 2021 zal de nieuwe LTS (long term support) versie van .Net gelanceerd worden en dit belooft een belangrijke versie te worden aangezien. Waar tot nu toe .Net Framework en .Net Core naast elkaar bestonden, ontstaat er nu nog maar 1 .Net. Deze versie is cross platform en kan gebruikt worden voor een zeer veelzijdig inzet gebied. Denk hierbij aan web applicaties, desktop applicaties (voor Windows, Linux en MacOS), mobile apps (voor iOS en Android), Cloud computing, IoT en Artificial Intelligence. Zie ook onze blog post ‘De toekomst van .NET’.

Toekomstige C# Features

De release van C# wordt voortaan gekoppeld aan de release van .Net en is dus elk jaar in november te verwachten. In deze release van C# is weer veel aandacht besteed aan het vereenvoudigen van veel gebruikte constructs en boilerplate code. Op deze manier wordt de code overzichtelijker en korter (dus sneller te ontwikkelen met minder fouten).

In de onderstaande code voorbeelden zie je nog een aantal rode squigglies. Dat komt omdat C# 10 nog in ontwikkeling is. Uiteraard zal het in de uiteindelijk versie zonder de foutmeldingen functioneren.

Records

Laten we eerst nog even teruggaan naar C# 9 waarin we kennis maakten met ‘Records’. In onderstaande code zie je de record Person. Een record is een soort lichtgewicht immutable class. Je kunt een instantie van een Person object creëren en in de object-initializer de waardes voor FirstName en LastName opgeven. Echter zijn deze waardes hierna niet meer aan te passen aangezien er geen “set” maar een “init” is gebruikt bij het definiëren van de property.

Een van de belangrijkste redenen om een Record te gebruiken is de mogelijkheid om 2 objecten op basis van de waardes te vergelijken en niet op de referentie. Kijk maar eens naar regel 18. Als Person een class was geweest, dan waren de variabele “person” en “originalPerson” niet gelijk aan elkaar geweest omdat ze niet verwijzen naar hetzelfde object. Bij Records zijn ze wel aan elkaar gelijk omdat de waardes in de records aan elkaar gelijk zijn. Ook de == operator zal true evalueren.

In C# 10 is er een toevoeging: Waar in C# 9 een Record altijd een Class was, kun je nu aangeven of het een Class-Record of een Struct-Record is. Zie de definitie record struct Person in onderstaand voorbeeld.

Functioneel is een record struct bijna identiek aan een record class, echter bevinden deze zich niet op de Heap maar op de Stack zoals je ook gewend bent van “normale” structs.

Op regel 10 van het voorbeeld zie je de with statement. Hier wordt feitelijk een kopie getrokken van “person”, maar de waarde voor “LastName” wordt vervangen. Doordat deze with statement nu ook moet werken met struct-records heeft dat tot gevolg dat with nu werkt op alle value-types zoals tuples.

Required Keyword

In het voorgaande voorbeeld is het dus mogelijk om een record aan te maken van het type Persoon en dan in de object-initializer waardes op te geven voor FirstName en LastName. Eenmalig, want daarna is het immutable. Echter is het ook mogelijk om alleen de FirstName of alleen de LastName op te geven waardoor je wellicht met incomplete data werkt. Omdat te voorkomen is het keyword required toegevoegd aan C# 10.

 

Auto backing Field

Stel je wilt dat tijdens het zetten van de waardes nog een Trim() wordt uitgevoerd? Dan kun je dus de auto-properties niet gebruiken, maar moet je een private variable _firstName maken en deze in init of setter vullen door middel van een trim op de value.

In C# 10 is dat ook vereenvoudigd door middel van een auto backing field. In het voorbeeld hieronder zie je dat de Init implementatie gebruikt maakt van “field”. Deze variabele is nergens gedefinieerd en is ook nergens anders aan te spreken dan binnen de Init, maar maakt het wel mogelijk om deze private field te vullen met de getrimde value.

 

Argument null checks

Elke C# ontwikkelaar heeft regelmatig code geschreven om te controleren of de argumenten van een methode wel gevuld zijn en anders een InvalidArgumentException te initiëren.

In het bovenstaande voorbeeld zie je de methode WriteToFile. Wanneer je wilt controleren of filePath wel een waarde heeft, dan kun je geen gebruik meer maken van de expression-bodied notatie, maar moet je echt een method body schrijven met een null check. Met C# 10 is dat veel eenvoudiger gemaakt: je hoeft alleen 2 uitroeptekens achter het argument te zetten!

 

Namespace aanpassingen

Een kleine aanpassing: de notatie van namespaces. Aangezien je altijd in een namespace gebruikt en dat alles daarom inspringt vanaf de linker kantlijn, is dat eigenlijk wel zonde van de ruimte. Voortaan kun je bovenin aangeven wat de namespace is en dat geldt dan voor het gehele bestand.

Ook zal elke c# ontwikkelaar het gestoei met usings herkennen. Als je een stuk code kopieert van het ene bestand naar het andere, dan moet je alle usings weer op order brengen. C#10 introduceert ‘Global Usings’. Wanneer je ergens een global using definieert, dan zijn ze overal in het project automatisch bekend. Het wordt aangeraden om 1 bestand te maken met daarin alle global usings. 

Wanneer een namespace nergens gebruikt wordt, dan kleurt deze grijs en kun je ze veilig verwijderen. In de overige bestanden hoef je deze dus niet meer erbij te zetten. De oplettende lezer had waarschijnlijk al gezien dat er in het voorbeeld gebruik gemaakt wordt van Top-level statements waardoor men geen “program” class en “main” methode hoeft te schrijven. In onderstaand voorbeeld zie je dus dat het bestand veel korter is door het ontbreken van de usings, class en methode.

 

ASP.Net minimal API

Bij ASP.Net wordt slim gebruik gemaakt van deze nieuwe language features.  Het moet mogelijk zijn om supersnel, met een paar regels code een WebApi in de lucht te brengen. Zo is de startup class optioneel geworden.

 

In het program.cs bestand wordt vervolgens in een top-level statement een WebApi gedefinieerd.

 

 

In deze 3 regels is er een WebApi gedefinieerd met een route “/” die “Hello World!” retourneert. Meerdere Api endpoints aanmaken is super eenvoudig. Dat kan door een extra Get te mappen op een andere route. De method body kan vervolgens een eenvoudige response geven of uitgebreidere business logic aanroepen die elders in het project is ondergebracht.

 

 

 Uiteraard is het bij grotere projecten nog steeds nodig (en/of overzichtelijker) om met losse controllers te werken, maar deze beknopte notatie is om Ideaal voor Microservices of om snel even wat mocken.

 

Kortom, C# 10 is geen revolutie, maar bevat diverse handige nieuwe features die er voor zorgen dat je makkelijker, sneller en overzichtelijker code kunt schrijven. Weer een mooie stap vooruit voor een taal die toch al geweldig is (persoonlijke mening 😉). 

 

Meer informatie over Microsoft oplossingen, C# of .NET?

Neem dan contact op met Christian. Hij wil je er graag alles over vertellen.

Interesse in een gesprek?

neem contact op met Christian Peeters

Laat uw gegevens achter

We nemen contact met u op!

Zie onze privacyverklaring.

Contact met Senet

Senet Eindhoven
Gestelsestraat 258
5654 AM Eindhoven
Bekijk op kaart

+31(0)40-2930395

KvK nummer: 17115078
Btw nummer: NL807989083B01