C# 11 İle Gelen 5 Yenilik
Selamlar,
Bu makalede C# 11 ile kesin olmamakla beraber, karşımıza çıkması muhtemel olan yeniliklerden bahsedeceğiz.
C# 11 İçin Hazırlık:
Öncelikle Visual Studio 2022 indirilir. Sonra C# 11 Preview özelliklerin VS 2022 altında çalışılabilmesi için, aşağıdaki gibi “Visual Studio Installer” altında More => Update settings seçilir.
Karşımıza gelen ekranda, aşağıda görüldüğü gibi Update channel => Preview seçilir ve => Bu makale itibari ile “17.2.0 Preview 5.0” sürümü indirilir.
Yeni Bir Konsol Uygulaması Yaratma:
Aşağıda görüldüğü gibi Preview .Net 7.0 sürümü seçilerek yeni bir Console Application oluşturulur.
Son olarak, Visual Studio 2022’de solution çift tıklanarak => “<LangVersion>preview</LangVersion>” tanımlaması aşağıdaki gibi solution dosyasına eklenir.
1-) Newlines in string interpolations:
İlk örneğimiz için, aşağıda görüldüğü gibi yeni bir Channel sınıfı, subscriberları ile birlikte yaratılır. Ayrıca “SubCount” adında toplam üye sayısını veren, bir Property’si bulunmaktadır.
1 2 3 4 5 6 7 8 9 10 11 |
public class Channel { public int SubCount => Subscribers.Count; public List<string> Subscribers = new() { "Bora", "Burak", "Engin", "Mehmet" }; } |
Aşağıda görüldüğü gibi, kodda herhangi bir bölme sınır gözetmeksizin, yeni bir satıra rahatlıkla geçilmektedir. Şahsen, saladığı okunuş kolaylığından dolayı, bu özelliği bir başka sevdim. Aynı kodu .Net 6.0 / C# 10 ile yazmaya kalkarsanız, hata alırsınız.
1 2 3 4 5 6 7 8 |
Console.WriteLine($"First Rank Subscriber With First Letter B is:{channel .Subscribers .Where(s => s.Substring(0, 1).ToUpper() == "B") .First()}"); Console.WriteLine($"This channel has:{channel.SubCount} subscribers."); |
2-) Parameter Null Checking
Aşağıda görüldüğü gibi, ilgili Channel’a yeni bir üye eklenebilmesi için, “AddSubscriber()” adında yeni bir method eklenmiştir. Normal şartlarda yeni bir üye eklerken, yorumlanan satırda olduğu gibi “subscriber == null” kontrolü yapılmalı ve eğer null ise “Exception” fırlatılmalıdır. Ama C#11 ile gelen, “string subscriber !!” şeklinde bir tanımlama ile, buna gerek kalmamış ve ilgili değişkenin null olması durumunda, otomatik hata fırlatılmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class Channel { public int SubCount => Subscribers.Count; public List<string> Subscribers = new() { "Bora", "Burak", "Engin", "Mehmet" }; /* public void AddSubscriber(string subscriber) { if (subscriber == null) { throw new ArgumentNullException(nameof(subscriber)); } Subscribers.Add(subscriber); } */ public void AddSubscriber(string subscriber!!) { Subscribers.Add(subscriber); } } |
1 |
channel.AddSubscriber(null); |
3-) List Patterns
Artık belirli bir liste içinden istenen elemanların alınması için, .Net 7.0 ile kullanabileceğimiz çok güzel özellikler gelmektedir. Aşağıda görüldüğü gibi, Channel sınıfına “NewStringSubscribers” string[ ] dizisi eklenmiştir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class Channel { public int SubCount => Subscribers.Count; public List<string> Subscribers = new() { "Bora", "Burak", "Engin", "Mehmet" }; public string[] NewStringSubscribers = new string[] { "Ayse", "Veli", "Ahmet", "Burak", "Osman" }; public void AddSubscriber(string subscriber!!) { Subscribers.Add(subscriber); } } |
1. Aşağıdaki pattern’de, “Subscribers” içinde “Bora” ilk ve sonrasında farklı elemanların olup olmadığı pattern’i => “true” sonucunu döner.
1 2 3 4 |
var boraWasFirst = channel.Subscribers is ["Bora", ..]; Console.WriteLine($"Bora is first: {boraWasFirst}"); |
2. Aşağıdaki örnekde, “Subscribers” içinde “Bora” ilk ve , “..“, “Mehmet” son patterni yazılmış ve doğruluğu ekrana basılmıştı. Ortalarında başka elemanların olduğu “..” karakteri ile tanımlanmıştır.
1 2 3 4 |
var boraFirstAndBurakLast = channel.Subscribers is ["Bora", .., "Mehmet"]; Console.WriteLine($"Bora is first and Mehmet is last: {boraFirstAndBurakLast}"); |
3. Aşağıdaki örnekde “NewStringSubscribers” içerisinde => “_” başta bir eleman var. Sonra “Veli” ve dizinin son elemanı “Osman” şeklinde bir pattern yazılmıştır. Dizideki “Veli” ve “..” “Osman” arasındaki elemanlar, => “subscribersBetweenVeliAndOsman” değişkenine bu pattern sayesinde atanmışlardır. Daha sonra filitrelenen bu aradaki elemanlar, bir loop içinde ekrana basılmıştır.
1 2 3 4 5 6 7 8 9 |
if (channel.NewStringSubscribers is [_, "Veli", .. var subscribersBetweenVeliAndOsman, "Osman"]) { foreach (var subscriber in subscribersBetweenVeliAndOsman) { Console.WriteLine($"{subscriber} is between Veli and Osman"); } } |
4. Aşağıdaki örnekde Channel class’ına, NumberList adında “int[ ][ ]” çift boyutlu bir sayı dizisi eklenmiştir. Yeni yazılacak bir pattern ile, içinden [10,11]=> sayılarını alalım..
Pattern : [.., [_, .. int[] secretNumbers, _]] =>
- Bir dizi içindeki son eleman yani son dizi şu şekilde filitrelenir. Çünkü, bir dizi içinde her eleman, yine farklı bir dizidir. “[.. , [ ]]” : Bu pattern ile filitrelenen elemanlar bunlardır => [9,10,11,12]
- “[9,10,11,12]” dizisi içinde de [10 ,11] sayıları, secretNumbers’a şu şekilde atanır. Ortadaki eleman, baştaki ve sondaki elemanlar “_” ile elenerek, ortası alınır (“_,..,_”)=> “[_, .. int[] secretNumbers, _]“. Arada kalan elemanlar scretNumbers int[ ] dizisine atanır. Daha sonrasında secretNumbers dizisi, bir loop içinde gezilerek ekrana aşağıda görüldüğü gibi basılır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
if (channel.NumberList is [.., [_, .. int[] secretNumbers, _]]) { foreach (var number in secretNumbers) { Console.WriteLine($"Secret Number: {number}"); } } public class Channel { . . public int[][] NumberList = new[] { new int[] { 1, 2, 3,4 }, new[] { 5, 6,7,8 }, new[] { 9,10,11,12 } }; } |
Sonuç ekranı, aşağıdaki gibidir..
4-) Generic Attributes
Aşağıda görüldüğü gibi “<T>” tipinde C# 11 sayesinde Generic bir Attribute oluşturulmuştur. Böylece Attribute’a ait parametreler istenen tipde atanabilecek ve böylece farklı tipler için farklı Attributelar oluşturmaya gerek kalmayacaktır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class GenericAttribute<T> : Attribute { private T name { get; set; } private T action { get; set; } public GenericAttribute(T name, T action) { this.name = name; this.action = action; } public T Name { get { return name; } } public T Action { get { return action; } } } |
Örnek kullanım senaryosu, aşağıdaki gibidir. GenericClass’a ait “GetName()” ve “ChildMenuRowOfParrent()” methodlarına, Custom “GenericAttribute()”‘una “<int> ve <string>” tipinde farklı parametreler atanmıştır.
1 2 3 4 5 6 7 8 |
public class GenericClass { [GenericAttribute<string>("Generic Example Class", "Get Name of Student")] public string GetName() => default; [GenericAttribute<int>(3, 4)] public string ChildMenuRowOfParrent() => default; } |
5-) *Static Abstract Interface Methods
Geldik nerde ise hiç duyurulmayan benim favori yeni özelliğime. Aşağıda görüldüğü gibi “IGenBext<T>” Interface’i içinde, static abstract bir “operator ++()” adında bir method tanımlanmıştır.
Not: “++(T other)” =”Anlamı, şu türde <T> tipinde bir sonraki değeri üret”‘dir. Kısaca ilgili operator ++() methodu, RepeatSequence struct’ı, bir loop içinde çağrılır ise ve her iteration içinde “Value ++” şeklinde arttırılır ise, bu method tetiklenecektir.
- RepeatSquence struct’ı => IGenNext<RepeatSquence>’dan yani, <T> yerine kendisinin verildiği IGenNext interfaceden türetilmiştir.
- “public string Value = Num.ToString()“: Value property’sine, ilk değer olarak “1” atanmıştır.
- “public static RepeatSequence operator ++(RepeatSequence other)“: IGenNext’den türetildiği için, static Method operator() burada tanımlanmıştır.
- Geri dönüş tipi, gene kendisidir (RepeatSequence).
- “++(RepeatSequence other)” => Bir sonraki değer yine “RepeatSequence” tipinde üretilecek demektir.
- “=> other with { Value = other.Value + Num }” : “with” keyword’ü ile, other değişkenine var olan RepeatSequence struct’ı, Value değeri (Value + Num) şeklinde güncellenerek clonelanır, ve bu “RepeatSequence” tipindeki “other” değişkeni geri dönülür.
- ToString() methodu override edilerek, “RepeatSquence” struct’ının => “Value” değerinin geri dönülmesi sağlanır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public interface IGetNext<T> where T : IGetNext<T> { static abstract T operator ++(T other); } public struct RepeatSequence : IGetNext<RepeatSequence> { public RepeatSequence() { } private const int Num = 1; public string Value = Num.ToString(); public static RepeatSequence operator ++(RepeatSequence other) => other with { Value = other.Value + Num }; public override string ToString() => Value; } |
Kullanım şekli, aşağıdaki gibidir.
- Görüldüğü üzere her “for loop” içinde, val++ yazılarak => RepeatSequence struct’ının static “operator ++()” methodu çağrılmış ve o da geriye güncellenmiş “Value“‘lu, clonelanmış yeni bir “RepeatSequence” struct’ı dönmüştür.
- Console.Writeln () ile => “RepeatSequence” struct’ının, override edilmiş ToString() methodu ile Value parametresi, ekrana basılmıştır.
1 2 3 4 |
var val = new RepeatSequence(); for (int i = 0; i < 10; i++) Console.WriteLine(val++); |
Sonuç Ekranı:
Geldik bir makalenin daha sonuna. Bu makalede, C# 11 ile gelen en beğendim 5 yenilikten bahsetmek istedim. Şahsen, C# beni aradan geçen 20 yıla rağmen halen şaşırtmaya ve heycanlandırmaya devam ediyor. Microsoft ve Core ekibi .Net 7.0 C# 11 ile gene harika bir iş çıkarmış.
Yeni bir makalede görüşmek üzere hepinize hoşçakalın.
Source Code: https://github.com/borakasmer/C-11FiveNewFeatures
Source:
- https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11#static-abstract-members-in-interfaces
- https://devblogs.microsoft.com/dotnet/early-peek-at-csharp-11-features/#c-11-preview-allow-newlines-in-the-holes-of-interpolated-strings
- https://dev.to/dotnetsafer/c-11-is-coming-5-features-that-will-blow-your-mind-3o7h
- https://www.youtube.com/watch?v=ljwz-YZZZ7g
- https://youtu.be/z7bW83Xr1R0
Makale için teşekkürler hocam. Parameter Null Checking kaldırıldı diye microsoftun bloğunda okumuştum sanırım. İleriki versiyonlarda tekrar ekleyebiliriz demişlerdi.
Merhaba Hocam,
Makale için çok teşekkürler hocam
Ben Teşekkür ederim..
bora beyy .net 6 için sıfırdan c# dersi yapmayı planlıyor musunuz? planda yoksa lütfen bi düşünün. bu arada siteniz çok hoş. yer imlerime ekledim
Teşekkürler. Planlıyorum..