Svaki put kad isprobam novu verziju C# želim vidjeti koje od novih mogućnosti ovog jezika ću ubuduće najviše koristiti.
Često pregled nove verzije jezika započinjemo od glavne teme te verzije. Više prethodnih verzija C# imalo je svoju glavnu temu – najvažniji feature koji je objavljen u pojedinoj verziji. Najbolji primjer je podrška za asinkrono programiranje, koristeći ključne riječi async i await, u C# 5. S obzirom da je C# 10 objavljen samo godinu dana nakon što je izašla prethodna verzija nije bilo dovoljno vremena da se napravi neki veliki novi feature koja bi bio glavna tema ove verzije.
Što nam donosi C# 10 je nastavak razvoja featurea koji su bili glavne teme u prethodne dvije verzija C#: records i pattern matching. Tu je i niz featurea čiji zadatak je ispolirati određena područja te napraviti jezik elegantnijim.
Kada sam odlučivao koji feature dodati u ovu listu gledao sam koliki utjecaj će pojedini feature imati na načina na koji koristimo C# i koliko će promijeniti izgled izvornog koda. Za jedan od featurea koji je na ovom popisu možemo reći da nije veliki feature, ali ispravlja jednu nelogičnost u jeziku koja mi baš upada u oči te sam ga stoga uvrstio na ovaj popis.
Record structs
Do sada je record mogao biti samo reference type podatak, poput klase. Počevši od C# 10 možemo deklarirati value type record koristeći record struct ili readonly record struct.
U sljedećih par primjera vidjeti ćemo da specificiranje kako se radi o struct record radimo jednostavno dodavanjem ključne riječi struct iza record.
Pogledajmo record struct deklariran koristeći positional properties:
public record struct Department (string Name, string Description);
Naravno, nije nužno koristiti positional properties kao što vidimo u idućem primjeru gdje dodavanjem ključne riječi readonly kreiramo readonly record struct:
public readonly record struct Company { public string Name { get; init; } public string CountryHQ { get; init; } }
Uz to što su record struct i readonly record struct value type, druga razlika njih u odnosu na obični stari record koji je reference type tiče se positional properties. Naime, positional properties su nepromjenjivi (immutable) u slučaju običnih records i u slučaju readonly record structs, ali su promjenjivi (mutable) u slučaju record struct.
U C# 10 uvedena je i mogućnost da naglasimo da se radi o reference type record tako što ćemo iza ključne riječi record dodati class, pa time record class znači isto što i samo record.
Osobno smatram da je u redu ne naglasiti da record je reference type tako što se piše record class, već je bolje koristiti činjenicu da se podrazumijeva da se radi o reference type record kada se piše samo record. Pogotovo pošto te dvije ključne riječi, record i class, svaka zasebno imaju (toliko) drugačija značenja.
Kada odabiremo hoćemo li koristiti običan stari reference type record ili record struct, možemo upotrijebiti isti logiku kao i u slučaju kada biramo između tradicionalnih class i struct.
Global using directives
Do sada je velika većina C# datoteka na svom početku imala iste linije koda – linije koda u kojima se iza ključne riječi using nalazilo ime nekog od često korištenih namespacea.
Počevši od C# 10 možemo prestati ponavljati iste linije na početku većine datoteka te samo jednom napisati using direktive koje su iste u nizu datoteka koristeći novi feature C# global using.
Na primjer, kada koristimo klase iz System.Text namespacea u više C# datoteka, ako koristimo C# 10 dovoljno je napisati samo u jednoj datoteci using ako ispred dodamo global:
global using System.Text;
U Blazoru od prije imamo sličnu mogućnost izbjegavanja ponavljanja using deklaracija na početku svake datoteke. Tamo je mehanizam drugačiji – Blazor koristi datoteku _Imports.razor te svaki namespace koji se u toj datoteci navede koristeći ključnu riječ using automatski je uključen u sve C# datoteke za pojedine Blazor komponente. Valja primijetiti da u slučaju Blazora ne koristimo ključnu riječ global ispred using, nego samo stavimo sve using deklaracije u datoteku s imenom _Imports.razor.
File-scoped namespace declaration
Nakon što smo pogledali novu mogućnost C# koja utječe na sam početak datoteke izvornog koda pogledajmo sada što se mijenja u izgledu preostalog dijela datoteke.
Velika većina linija u C# datoteci počinje s praznim prostorom na lijevoj strani.
Vertikalni prostor na lijevoj strani ostaje neiskorišten u starijoj verziji C#
Možemo bolje iskoristiti taj prazan prostor na lijevoj strani – samo trebamo u novoj verziji C# iza deklaracije namespacea staviti točka-zarez te više ne trebamo uvlačiti sve iduće linije koda. Tada nam niti ne trebaju vitičaste zagrade koje omeđuju sadržaj namespacea.
Na primjer, možemo jednostavno reći da se sav sadržaj datoteke nalazi u namespaceu CompanyXY tako da napišemo:
namespace CompanyXY;
Pogledajmo kako sada izgleda izvorni kod iz primjera od maloprije:
Prostor na ekranu se koristi efikasnije uz pomoć file-scoped namespace declaration u C# 10
Sadržaj unutar record ili klase je i dalje uvučen, kao i sadržaj metoda (čime je lako vizualno odrediti što je sadržaj pojedine metode), ali uštedjeli smo onaj vertikalni prostor koji je prije bio prazan zato što je cijeli namespace bio uvučen.
Kada na ovaj način definiramo namespace, tada sav sadržaj datoteke pripada tom namespaceu, neovisno o tome radi li se o klasi, strukturi, interfaceu itd.
Constant interpolated strings
Ovo je mala novost u C#, ali po mom mišljenju radi se o dobrodošloj promjeni jer ispravlja jednu nelogičnost u jeziku: naime, kada spajam dva konstanta stringa koristeći string interpolation očekujem da rezultat isto bude konstantni string. Ali, sve do C# 10 nismo mogli deklarirati kao konstantu rezultat spajanja konstantnih stringova dobiven koristeći string interpolation.
Kao što možemo vidjeti iz sljedećeg primjera string interpolation sada razumije da je kombinacija nekoliko konstanti konstanta.
const string companyFoundedYear = "1921"; const string companyFounder = "John Smith"; const string message = $"Founded in {companyFoundedYear} by {companyFounder}.";
Je li C# 10 korak u pravom smjeru?
C# 10 donosi niz poboljšanja – možda su ta poboljšanja mala, ali ja smatram da će ta poboljšanja pomoći programerima da pišu bolji kod. Dobro je što su ispeglani neki dijelovi C# i što su neki dijelovi jezika elegantniji.
Moje mišljenje je da C# 10 je korak u pravom smjeru. To nije veliki korak, kao što su bili veliki koraci neke od prethodnih verzija, ali uzmimo u obzir da nikada prije nova verzija C# nije izašla tako brzo nakon prethodne verzije. A kad smo kod toga, plan je da nova verzija C# izađe svake godine, zajedno s novom verzijom .NET te će biti zanimljivo pratiti kako će ta činjenica ubuduće utjecati na razvoj jezika.
- Najvažnije novosti u C# 10 - 09.11.2021.
- Manje poznate mogućnosti C# 9 - 18.06.2021.
- Pattern matching u C# 9 – korak u pravom smjeru - 05.03.2021.