Bilindiği üzere geçtiğimiz gün .NET 10 çıktı ve beraberinde C#14 ile birlikte yeni özellikler geldi. Bunların arasından geliştirici deneyimini ve kod kalitesini doğrudan etkileyen daha ilginç yeniliklerden bazılarını aktaracağım.
Field-backed Properties
C# 14 ile birlikte gelen en dikkat çekici yeniliklerden biri “field-backed properties” yani alan destekli özelliklerdir. Bu özellik bize property accessor (erişimci) bloklarında kullanılabilen yeni bir field anahtar sözcüğü getirir. Bu anahtar sözcük property’nin otomatik olarak oluşturulan arka plan alanına (backing field) başvurmayı sağlar.
C#’ın ilk sürümlerinde property böyle manuel oluşturuluyordu:
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}C# 3.0’dan itibaren gelen otomatik özellikler (auto-properties) bu süreci sadeleştirir:
public int Age { get; set; }Bu kodu yazdığınızda C# derleyicisi sizin adınıza gizli bir backing field oluşturur.
private int <Age>k__BackingField;
public int Age
{
get { return <Age>k__BackingField; }
set { <Age>k__BackingField = value; }
}Bu field ismi gizlidir ve doğrudan erişilemez. Ancak bu yapı, sadece “get” ve “set” işlemlerinde hiç özel mantık yoksa işe yarar. Eğer özel bir doğrulama veya işlem eklemek isterseniz otomatik property kullanamazsınız çünkü get veya set gövdesi açamıyorsunuz.
Yeni Özellik: Field-backed Property
C# 14 ile gelen yenilik burada devreye giriyor. Yeni bir anahtar sözcük olan field, derleyici tarafından otomatik oluşturulan backing field’a erişim sağlar. Artık özel bir mantık yazarken bile manuel olarak bir alan tanımlamanıza gerek yok.
public int Age
{
get;
set
{
if (value < 0) throw new ArgumentOutOfRangeException();
field = value;
}
}Burada “field” derleyicinin otomatik oluşturduğu gizli alanı temsil eder, “get” kısmı yine otomatik olarak oluşturulur (çünkü elle yazmadık), “set” kısmında özel bir mantık yazabiliyoruz ve doğrudan “field” değişkenini kullanabiliyoruz.
Sonuçta hem auto-property’nin sadeliği hem de manuel property’nin esnekliği birleşmiş olur.
Derleyici düzeyince ne olur?
private int <Age>k__BackingField;
public int Age
{
get { return <Age>k__BackingField; }
set
{
if (value < 0) throw new ArgumentOutOfRangeException();
<Age>k__BackingField = value;
}
}Bu özellik kodu sadeleştiriyor çünkü ayrı bir “_field” tanımlanmıyor, kapsülleme korunuyor çünkü “field” hala gizli ve dışarıdan erişilemez, okunabilirlik artıyor ve hata riski azalıyor.
Extension Members
Bir extension method, bir sınıfın kaynak koduna erişimin olmasa bile (örneğin string veya List gibi) o sınıfa yeni bir metot eklemeni sağlar. Ama aslında bu metot static bir metottur. Bu kolaylık sağlıyor.
public static class StringExtensions
{
public static string Capitalize(this string s)
{
return s[..1].ToUpper() + s[1..];
}
}Diyelim ki IEnumerable koleksiyonlarına IsEmpty adında bir property eklemek istiyorsunuz:
// Hatalı extension tanımlanması
public static bool IsEmpty(this IEnumerable<T> source) => !source.Any();Burada property tanımlayamazsınız çünkü extension sadece method destekler. Yani items.IsEmpty yazamazsınız, mecburen items.IsEmpty() metodu gibi çağırmanız gerekir.
Bir List için List.Empty gibi bir static property eklemek de mümkün değildir. Çünkü extension mekanizması sadece instance nesnelere uygulanabilir. Yani List türünün kendisine static bir özellik ekleme şansınız yoktur.
C# 14 ile birlikte bu iki sınır tamamen ortadan kalkıyor. Yeni “extension members” yapısı sayesinde artık property tanımlayabilirsiniz ve artık hem instance hem static seviyede genişletme yapabilirsiniz.
Örnek bir “instance extension” tanımı:
extension(string s)
{
public string Capitalize() => s[..1].ToUpper() + s[1..];
}Örnek bir property tanımı:
extension<T>(IEnumerable<T> source)
{
public bool IsEmpty => !source.Any();
}Örnek bir “static extension” tanımı:
extension<T>(List<T>)
{
public static List<T> Singleton(T value) => [value];
public static List<T> Empty => [];
}Bu sayede static extension kullanarak böyle bir kullanım yapılabiliyor:
var single = List<int>.Singleton(42);
var empty = List<int>.Empty;Yani List tipinin kendisine statik üyeler eklenmiş gibi davranabilirsiniz. Bu daha önceki C# sürümlerinde imkansızdı.
Null-Conditional Assignment
C# 6 sürümüyle birlikte, null-conditional operator (?.) dilde yerini almıştı. Bu operatör bir nesne null değilse onun property’sine veya alanına erişmeyi sağlar. “null” kontrolü yaparak güvenli bir erişim sağlıyordu.
Örneğin burada eski bir örnek yapalım.
Product? item = GetProduct();
if (item is not null)
{
item.Name = "phone";
}Bu özellikle çok sayıda property güncellemesi yaparken gereksiz null kontrolleriyle kodun uzamasına neden olurdu.
C# 14 bu durumu sadeleştiriyor. Artık null koşullu operatör (?.) atama işlemlerinde de kullanılabilir. Örneğin buradaki kod bloğunda yalnızca item null değilse name property’e değer atanıyor:
Product? item = GetProduct();
item?.Name = "phone";Ne kadar da kısalttık değil mi? Bu yenilik küçük ama etkili bir geliştirmedir. Artık null kontrolleri için gereksiz if blokları yazmaya gerek kalmadan, tek satırda hem güvenli hem de temiz atama işlemleri yapılabilir. Özellikle veri güncellemelerinde “objeyi al ve null değilse ata” gibi klasik desenleri yazarken kodun okunabilirliğini ciddi biçimde artırır.
Collection Expressions
C# 12 sürümüyle birlikte, koleksiyon ifadeleri (collection expressions) tanıtılmıştı.
Bu özellikle diziler veya listeler gibi koleksiyonları daha kısa ve okunabilir şekilde tanımlamayı sağlıyordu.
int[] numbers = [1, 2, 3];
List<string> names = ["Recep", "Muslim", "Türk"];C# 14 bu özelliği daha da güçlü hale getiriyor. Yeni sürümle birlikte koleksiyon ifadeleri artık daha fazla yerde ve daha esnek biçimde kullanılabiliyor.
yield return ifadelerinde, params parametrelerinde, IEnumerable dönüşlerinde ve hatta LINQ sorgularında bile kullanılabilecek.
Örnekler:
// Birinci örnek
IEnumerable<int> GetNumbers() => [1, 2, 3, 4];
// İkinci örnek
int[] baseArray = [1, 2, 3];
int[] combined = [..baseArray, 4, 5];
// Üçüncü örnek
IEnumerable<string> Names()
{
yield return ["Recep", "Muslim", "Türk"];
}
Dikkat ederseniz bu özellik sayesinde C# artık daha modern ve hatta Python benzeri bir sözdizime yaklaşıyor. Özellikle LINQ sorguları ve generator (yield) yapılarında daha kısa kod yazmayı mümkün kılıyor.
Sonuç
C# 14 görüldüğü üzere geliştirici deneyimini sadeleştirmeyi ve dilin modernliğini artırmayı hedefliyor. Field-backed properties ile getter/setter içinde manuel alan tanımlamayı ortadan kaldırıyor. Extension members ile artık sadece metot değil, özellikleri de genişletebiliyorsun (hem instance hem static). Null-conditional assignment ile null kontrolü yapmadan güvenli atama yapılabiliyor. Collection expressions ile koleksiyon oluşturmayı çok daha kısa ve okunabilir hale getiriyor.
Elbette hangi özelliğin daha faydalı olacağı tamamen proje türüne ve kullanım senaryosuna bağlı. Burada bahsetmediğim başka özellikler de mevcut. Hepsini merak edenler için Microsoft’un yayımladığı C# 14 yeniliklerinin tam listesi incelenebilir.



Yorum bırakın