> ## Content Index
> Fetch the complete content index at: https://hasan-aytac.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# C# 2026: field ve Null-Conditional Assignment ile Güvenli Modeller
- URL: https://hasan-aytac.com/csharp-2026-field-null-conditional-assignment/
- Published: 2026-10-13T08:58:19.000Z
- Updated: 2026-10-13T08:58:19.000Z
- Description: C# 14 field anahtar sözcüğüyle doğrulanan özellikler oluşturun; ?. atamalarının ne zaman çalıştığını ve nerede kullanılmaması gerektiğini örneklerle öğrenin.
- Author: Hasan Aytaç
- Tags: csharp, dotnet, programming, C# 2026, #editorial-csharp-2026

> **Sürüm notu:** Bu rehberdeki “2026” bir yıl ifadesidir. Aşağıdaki iki dil özelliği **C# 14** ile gelir; örnekler **.NET 10** üzerinde çalışır.

Bir özellik atandığında boşlukları temizlemek, negatif fiyatı reddetmek veya isteğe bağlı bir nesneye not eklemek sıradan işlerdir. Fakat bu küçük işler, modellerde tekrar eden backing field’lara ve uzayan null kontrollerine dönüşebilir.

C# 14 iki faydalı araç sunuyor: özellik erişimcilerinde `field` kullanımı ve atamanın sol tarafında null-conditional erişim. İkisi de kodu sadeleştirir; ancak doğrulama sorumluluğunu ortadan kaldırmaz.

Bu yazıda bir ürün modeli ve sipariş taslağı üzerinden hem normal akışı hem de hatalı girdilerin davranışını ele alacağız.

## 1\. field tam olarak neyi değiştiriyor?

Klasik yaklaşımda doğrulama yapan bir özellik için özel bir alan tanımlarız:

```csharp
private string _name = "Adsız ürün";

public string Name
{
    get => _name;
    set
    {
        if (string.IsNullOrWhiteSpace(value))
            throw new ArgumentException("Ürün adı boş olamaz.", nameof(value));

        _name = value.Trim();
    }
}

```

C# 14’te derleyicinin oluşturduğu backing field’a, erişimci içindeki `field` anahtar sözcüğüyle ulaşabiliriz. Böylece yalnızca alan bildirimini ve onu döndüren basit getter’ı kaldırırız; iş kuralı aynı yerde görünür kalır.

Bu özellik, `field` adlı bir değişken oluşturmanız anlamına gelmez. Bağlama duyarlı anahtar sözcük, ilgili özelliğin derleyici tarafından üretilen depolama alanını ifade eder.

## 2\. Doğrulanan bir ürün modeli

.NET 10 konsol projesindeki ayrı bir `Product.cs` dosyası şöyle olabilir:

```csharp
namespace CSharp2026.SafeModels;

public sealed class Product
{
    public string Name
    {
        get;
        set
        {
            if (string.IsNullOrWhiteSpace(value))
                throw new ArgumentException("Ürün adı boş olamaz.", nameof(value));

            field = value.Trim();
        }
    } = "Adsız ürün";

    public decimal Price
    {
        get;
        set => field = value >= 0
            ? value
            : throw new ArgumentOutOfRangeException(nameof(value), "Fiyat negatif olamaz.");
    }
}

```

Burada iki kural var: ürün adı boş bırakılamaz ve fiyat negatif olamaz. Örneğin:

```csharp
using CSharp2026.SafeModels;

var product = new Product
{
    Name = "  Klavye  ",
    Price = 1250m
};

Console.WriteLine(product.Name);  // Klavye
Console.WriteLine(product.Price); // 1250

```

`get;` otomatik getter’dır. Setter ise değeri doğrulayıp `field` alanına yazar. Getter ve setter’ı tek bir özellik içinde okuyarak saklanan değerin nereden geldiğini anlayabiliriz.

Başlangıç değerlerine de dikkat edin. `Name` için geçerli bir varsayılan metin verdik; `Price` için decimal’in varsayılanı olan sıfır geçerlidir. Property initializer, setter’ı çağırarak doğrulama yapmaz; backing field’ı başlatır. Bu nedenle başlangıç değerini de sizin doğru seçmeniz gerekir.

Gerçek uygulamanızda ücretsiz ürün kabul edilmiyorsa `value >= 0` yeterli değildir. Para birimi, hassasiyet ve yuvarlama gibi finansal kurallar da bu basit örneğin dışındadır. **Kısa sözdizimi, domain modelinin tamamlandığı anlamına gelmez.**

## 3\. Hatalı atama mevcut değeri bozmamalı

Doğrulamayı `field` atamasından önce yapmak önemlidir:

```csharp
try
{
    product.Price = -1m;
}
catch (ArgumentOutOfRangeException)
{
    Console.WriteLine(product.Price); // 1250
}

```

Setter önce koşulu kontrol eder. Geçersiz değer geldiğinde istisna oluşur, dolayısıyla eski fiyat korunur. Aynı davranış boş ürün adı için de geçerlidir.

Bu, testlerde özellikle kontrol edilmesi gereken bir ayrıntıdır. Sadece “istisna fırlattı mı?” sorusu yetmez; nesnenin hatadan sonra hangi durumda kaldığını da doğrulamalısınız.

Setter içine uzak servis çağrısı, dosya erişimi veya kapsamlı iş akışı koymak ise hâlâ kötü bir sürpriz yaratabilir. Bir özelliği atamak ucuz ve öngörülebilir olmalıdır. Daha karmaşık işlemler için niyeti açık bir metot tercih edin.

## 4\. Null-conditional assignment nasıl çalışır?

Sipariş taslağı modelimiz:

```csharp
namespace CSharp2026.SafeModels;

public sealed class OrderDraft
{
    public string? Note { get; set; }
    public int Quantity { get; set; }
}

```

C# 14 öncesinde isteğe bağlı bir taslağa not atarken çoğunlukla `if (draft is not null)` bloğu yazardık. Artık `?.` atamanın sol tarafında kullanılabilir:

```csharp
OrderDraft? draft = null;
int calls = 0;

draft?.Note = BuildNote();
Console.WriteLine($"Null taslakta çağrı sayısı: {calls}");

draft = new OrderDraft();
draft?.Note = BuildNote();
draft?.Quantity += 1;
Console.WriteLine($"Dolu taslakta çağrı sayısı: {calls}");
Console.WriteLine($"Adet: {draft?.Quantity}");

string BuildNote()
{
    calls++;
    return "Kapıya teslim";
}

```

Beklenen çıktı:

```text
Null taslakta çağrı sayısı: 0
Dolu taslakta çağrı sayısı: 1
Adet: 1

```

Buradaki kritik nokta, yalnızca atamanın atlanması değildir. **Alıcı null olduğunda sağ taraftaki ifade de değerlendirilmez.** İlk satırdaki `BuildNote()` hiç çağrılmaz. Bu davranış, not üretmenin pahalı olduğu veya başka bir yan etki oluşturduğu durumlarda önem kazanır.

Bileşik atamalar da desteklenir: `draft?.Quantity += 1` kullanılabilir. Fakat `draft?.Quantity++` ve `draft?.Quantity--` bu özelliğin desteklediği biçimler değildir. Örnekleri birbirine eşdeğer sanarak değiştirmeyin.

## 5\. Kısa yazmak her zaman doğru davranış değildir

Null-conditional assignment, **null olduğunda hiçbir şey yapılmaması gerçekten doğruysa** uygundur. İsteğe bağlı bir ekran ayarı, henüz oluşmamış bir önizleme nesnesi veya yardımcı görüntüleme durumu buna örnek olabilir.

Fakat sipariş tamamlama gibi bir işlemde taslağın bulunması zorunluysa, sessizce atlamak hatayı saklar. Böyle bir durumda açık kontrol daha doğru olur:

```csharp
ArgumentNullException.ThrowIfNull(draft);
draft.Note = "Onay için hazır";

```

Ayrıca `?.` thread safety sağlamaz. Paylaşılan nesnede `Quantity += 1` işlemini atomik hâle getirmez; eşzamanlılık için kilit, uygun atomik işlemler veya farklı bir durum yönetimi yaklaşımı gerekebilir.

Nullable reference types da bu resmin sadece bir parçasıdır. Anotasyonlar, derleyicinin olası null kullanımını raporlamasına yardımcı olur; dış sistemlerden gelen hatalı verilerin var olmayacağını garanti etmez. Giriş sınırlarında doğrulama yapmayı sürdürün.

## 6\. Projeye taşımadan önce kontrol listesi

- Hedef çerçeveniz `net10.0`, dil sürümünüz C# 14 mü?
- Varsayılan özellik değerleri domain kurallarına uygun mu?
- Geçersiz atama sonrasında eski değer korunuyor mu?
- Null durumunda işlemin atlanması gerçekten istenen davranış mı?
- Sınıfınızda zaten `field` adlı bir üye varsa anlam karışıklığı oluşuyor mu?

Son maddede gerekirse mevcut üyeyi yeniden adlandırın. `@field` veya `this.field`, mevcut bir üye ile yeni anahtar sözcüğü ayırt etmeye yardımcı olabilir. Bu özellikle eski kodları yeni derleyiciyle derlerken gözden geçirilmelidir.

## Sonuç: sade kod, açık kurallar

`field`, doğrulanan özelliklerde gereksiz alan tekrarını azaltır. Null-conditional assignment ise isteğe bağlı nesneler için kontrol akışını sadeleştirir. İkisinin de değeri, kodun niyetini görünür kılmalarıdır; zorunlu kontrolleri gizlemeleri değil.

[Çalıştırılabilir kod örneklerini indir — ZIP](https://hasan-aytac.com/content/files/2026/10/csharp-2026-code-samples.zip). `SafeModels` projesi ad temizleme, geçersiz girdiler, eski değerin korunması ve null atamalardaki yan etkiler için on doğrulama içerir.

## Kaynaklar ve devamı

- [Microsoft Learn — C# 14: field anahtar sözcüğü](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14?ref=hasan-aytac.com#the-field-keyword)
- [Microsoft Learn — C# 14: null-conditional assignment](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14?ref=hasan-aytac.com#null-conditional-assignment)
- [Microsoft Learn — Nullable reference types](https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references?ref=hasan-aytac.com)
- Önceki yazı: [Extension Members ile API tasarımı](https://hasan-aytac.com/csharp-2026-extension-members/).
- Sonraki yazı: [Async Streams ve Cancellation](https://hasan-aytac.com/csharp-2026-async-streams-cancellation/).

*Bu yazı yapay zekâ desteğiyle hazırlanmıştır. İndirilebilir örnekler .NET SDK 10.0.401 üzerinde, C# 14 ayarı ve uyarıları hata kabul eden yapılandırmayla derlenip çalıştırılmıştır.*