C# 15 Önizleme: Union, Closed ve Yeni Özellikler
C# 15, Kasım ayında.NET 11 ile birlikte yayımlanacak. Yeni dil özelliklerini beklemeden.NET 11 Preview 7 üzerinden bugün de deneyebilirsiniz. Sürüm; union types, closed hierarchies, güncellenmiş unsafe modelinin ilk önizlemesi, koleksiyon ifadelerine argüman geçme, extension indexer’lar ve etiketli break/continue gibi eklentiler getiriyor. Bu yazıda her özelliği kısa örneklerle ve resmi referanslara bağlayarak topluyorum.
Union types: izin verilen tipleri türde belirtmek
Bir union type, bir değerin hangi tipleri taşıyabileceğini tip sisteminde net biçimde ifade eder. object, marker interface veya soyut bir taban sınıfla çalıştığınızda çalışma zamanı tipi bu tabandan türeyen herhangi bir şey olabilir. Union ise değeri belirtilen case type‘lardan biriyle sınırlar; case tiplerinin birbiriyle kalıtım ilişkisi olması da gerekmez.
public record class Cat(string Name);
public record class Dog(string Name);
public record class Bird(string Name);
public union Pet(Cat, Dog, Bird);
Yukarıdaki Pet yalnızca Cat, Dog veya Bird tutabilir. Her case type Pet‘e örtük olarak dönüşür. Derleyici tüm kümeyi bildiği için null olmayan bir Pet üzerindeki switch ifadesi, discard veya default kolu olmadan da exhaustive kabul edilir:
Pet pet = new Dog("Rex");
string name = pet switch
{
Dog d => d.Name,
Cat c => c.Name,
Bird b => b.Name,
};
Union tipleri, izin verilen tip kümesini açıkça belirtme fikrinin somut bir ifadesi. Aynı fikir closed hierarchies’te ve planlanan closed enum’larda da uygulanıyor.
Closed hierarchies: kalıtım ağacını sınırlamak
Closed hierarchies aynı yaklaşımı kendi tasarladığınız sınıf hiyerarşilerine taşır. Bir sınıfa closed modifier’ı eklediğinizde sınıf örtük olarak abstract olur ve doğrudan türeyen tipler yalnızca aynı assembly içinde tanımlanabilir. Türetme uçlarını açık bırakmak yerine hangi alt tiplerin izinli olduğunu açıkça bildirmiş olursunuz.
public closed record class JobStatus;
public record class Queued : JobStatus;
public record class Running(int PercentComplete) : JobStatus;
public record class Completed(TimeSpan Elapsed) : JobStatus;
public record class Failed(string Error) : JobStatus;
Closed hiyerarşiler, union types ve planlanan closed enum’lar, izinli şekiller kümesini doğrudan tip sisteminde ifade eder. closed modifier’ının kalıtımla nasıl birleştiğine dair ayrıntılar için resmi closed modifier ve closed hierarchy patterns belgelerine bakılabilir.
Bellek güvenliği modelinin yeniden tasarımı (preview)
C# 15, unsafe‘in yeniden tasarımını başlatıyor: “burada pointer var” diyen bir sözdizim işareti olmaktan çıkıp, derleyicinin doğrulayamadığı ancak geliştiricinin üstlendiği bir sözleşmeye dönüşüyor. Bu,.NET 11 ve C# 15’te preview statüsünde bir özellik; model ve sözdizim.NET 12 ile C# 16 sürecinde değişebilir. Denemek için proje dosyasına açıkça opt-in eklemek gerekiyor:
<Features>$(Features);updated-memory-safety-rules</Features>
<LangVersion>preview</LangVersion>
Yeni modelde pointer tipleri için artık unsafe bağlamı zorunlu değil. Güvenli bir bağlamda pointer tipi bildirebilir, & ile adres alabilir, fixed statement kullanabilir, stackalloc‘u pointer’a dönüştürebilir ve unmanaged tip üzerinde sizeof uygulayabilirsiniz.
Pointer’ı dereference eden işlemler ise unsafe gerektirmeye devam ediyor: pointer indirection (*p), pointer üzerinden üye erişimi (p->m), pointer üzerinden eleman erişimi (p[i]), fixed-size buffer eleman erişimi ve function-pointer çağırma.
Bir üyenin imzasına unsafe modifier’ı eklendiğinde ise bu üye yalnızca unsafe bir bağlamdan çağrılabilir. Mevcut davranışa göre bu bir breaking change. Üye, çağıranlarının sözleşmeyi sağlamasını beklediğini bildirmiş oluyor; çağıran da ya bu koşulu sağlamalı ya da kendi bildiriminde unsafe modifier’ını ileterek güvensizliği yaymalıdır.
Önizleme özelliği olduğu için tasarım kesinleşmedi; ekip csharplang üzerinden geri bildirim topluyor.
Collection expression arguments
Koleksiyon ifadeleri birçok koleksiyon tipine dönüşebiliyor; ancak şimdiye kadar altta yatan constructor’a veya Create metoduna argüman geçirmek mümkün değildi. C# 15, en başa yazılan bir with(...) elemanı ekleyerek argümanları constructor’a veya factory metoduna iletmeyi sağlıyor. Bu, gelecek dictionary expressions söz dizimi için de gerekli bir temel; sözlükte çoğu zaman bir comparer belirtmek gerekir.
// Önce
List<string> names = new(capacity: values.Length * 2);
names.AddRange(values);
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Hello", "HELLO" };
// Sonra (C# 15)
List<string> names = [with(capacity: values.Length * 2),.. values];
HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO"];
Extension indexers
C# 14, extension member kavramını genişletmiş; metotların yanına property ve operator eklemeye de izin vermişti. C# 15 ise extension indexer‘ları getiriyor: alıcı üzerinde tanımlıymış gibi indeksleme yapılabiliyor. Indexer’lar static olamayacağı için extension container’ın adlandırılmış bir receiver içermesi gerekiyor.
// Önce: yardımcı metot
public static class SequenceExtensions
{
public static int ElementAtIndex(this IEnumerable<int> sequence, int index)
=> sequence.ElementAt(index);
}
int third = numbers.ElementAtIndex(2);
// Sonra (C# 15): extension indexer
public static class SequenceExtensions
{
extension(IEnumerable<int> sequence)
{
public int this[int index] => sequence.ElementAt(index);
}
}
int third = numbers[2];
Etiketli break ve continue
İç içe döngülerde dıştaki döngüyü kırmak genellikle bir flag, goto veya ayrı bir metot gerektirir. C# 15 ile döngüye etiket verilip break veya continue bu etiketi doğrudan hedefleyebiliyor.
// Önce: dış döngüyü kırmak için flag
bool found = false;
foreach (Warehouse warehouse in warehouses)
{
foreach (Bin bin in warehouse.Bins)
{
if (bin.Sku == requestedSku && bin.Quantity > 0)
{
reserved = Reserve(bin);
found = true;
break;
}
}
if (found)
break;
}
// Sonra (C# 15): döngüye etiket verip doğrudan kır
scan: foreach (Warehouse warehouse in warehouses)
{
foreach (Bin bin in warehouse.Bins)
{
if (bin.Sku == requestedSku && bin.Quantity > 0)
{
reserved = Reserve(bin);
break scan;
}
}
}
Bu yaklaşımın görünür kazancı, niyetin ek bir bayrak değişkeni olmadan doğrudan koda yansıması.
Önizlemeyi denemek
Özellikleri değerlendirmek için.NET 11’i indirip mevcut uygulamalarda C# 15’i açmak yeterli. Tam referans ve tartışmalar için resmi kaynaklar aşağıda..NET 11 Preview 7 kapsamında yayımlanan diğer platform yeniliklerine bakmak isteyenler .NET 11 Preview 7 Yayınlandı: Öne Çıkan Yenilikler yazısına göz atabilir.
Kaynaklar ve İleri Okuma
- Explore new features available in C# 15 preview (Bill Wagner,.NET Blog)
- What’s new in C# 15
- C# 15 union types
- Work with union types (tutorial)
- Union types referansı
- closed modifier referansı
- Closed hierarchy patterns
- Improving C# memory safety
- Unsafe code referansı
- Collection expressions referansı
- Extension keyword referansı
- dotnet/csharplang (dil tasarımı tartışmaları)







2 comments