Aracılığıyla paylaş


Boş değer atanabilir başvuru türleri

Null atanabilir başvuru türleri, kodunuzun çalışma zamanının System.NullReferenceExceptionoluşturma olasılığını en aza indiren bir özellik grubudur. Bu özel durumlardan kaçınmanıza yardımcı olan, referans tipini nullableolarak açıkça işaretleme özelliği de dahil, üç özellik bulunmaktadır:

  • Değişkenin başvuru yapılmadan önce null olup olmadığını belirleyen geliştirilmiş statik akış analizi.
  • Akış analizinin null durumunu belirlemesi için API'lere ek açıklama ekleyen öznitelikler.
  • Geliştiricilerin bir değişken için hedeflenen null durumunu açıkça bildirmek için kullandığı değişken ek açıklamaları.

Derleyici, derleme zamanında kodunuzdaki her ifadenin null durumunu izler. The null-state iki değerden birine sahiptir:

  • not-null: İfadenin null null olmadığı bilinmektedir.
  • belki-null: İfade olabilir null.

Değişken ek açıklamaları, başvuru türü değişkeninin null atanabilirliğini belirler:

  • null olamaz: Değişkene bir null değer veya null olabilir ifade atarsanız, derleyici bir uyarı verir. Null olamayan değişkenlerin varsayılan null durumu 'null değildir'.
  • nullable: Değişkene bir null değer veya belki-null ifade atayabilirsiniz. Değişkenin null durumu belki null olabilir olduğunda, değişkene başvurduğunuzda derleyici bir uyarı verir. Değişkenin varsayılan null durumu belki-null'tır.

Bu makalenin geri kalanında, kodunuzun bir null değerine başvuru kaldırdığı durumlarda uyarı üretebilecek olan bu üç özellik alanının nasıl çalıştığı açıklanır. Bir değişkenin göstericisinin üzerinden geçmek, aşağıdaki örnekte gösterildiği gibi . (nokta) operatörüyle üyelerinden birine erişmeyi ifade eder:

string message = "Hello, World!";
int length = message.Length; // dereferencing "message"

Değeri null olan bir değişkenin başvurusunu kaldırdığınızda, çalışma zamanı bir System.NullReferenceException oluşturur.

Benzer şekilde, bir nesnenin [] üyesine erişmek için gösterim kullanıldığında ve nesne null olduğunda uyarılar oluşturulabilir.

using System;

public class Collection<T>
{
    private T[] array = new T[100];
    public T this[int index]
    {
        get => array[index];
        set => array[index] = value;
    }
}

public static void Main()
{
    Collection<int> c = default;
    c[10] = 1;    // CS8602: Possible dereference of null
}

Şu konularda bilgi edineceksiniz:

  • Derleyicinin null durum çözümlemesi: derleyicinin, bir ifadenin null olmadığını veya belki null olabileceğini nasıl belirlediği.
  • Derleyicinin null durum analizi için daha fazla bağlam sağlayan API'lere uygulanan öznitelikler.
  • Null atanabilir değişken ek açıklamaları, değişkenler için amacınızı belirten bilgileri sağlar. Ek açıklamalar alanlar, parametreler ve dönüş değerleri için kullanışlıdır ve varsayılan null durumunu ayarlar.
  • Genel tür bağımsız değişkenlerini yöneten kurallar. Tür parametreleri başvuru türleri veya değer türleri olabileceği için yeni kısıtlamalar eklendi. Ek ?, null atanabilir değer türleri ve null atanabilir başvuru türleri için farklı şekilde uygulanır.
  • Nullable bağlam büyük projelerin taşınmasına yardımcı olur. Geçiş sırasında uygulamanızın bazı bölümlerinin null değer alabilen bağlamında uyarıları ve ek açıklamaları etkinleştirebilirsiniz. Daha fazla uyarıyı ele aldıktan sonra, projenin tamamı için her iki ayarı da etkinleştirebilirsiniz.

Son olarak, struct türleri ve dizileri için null durumu analiziyle ilişkili bilinen tuzakları öğrenirsiniz.

Bu kavramları C#'ta Nullable güvenliği ile ilgili Learn modülümüzde de inceleyebilirsiniz.

Null durum analizi

Null durum çözümlemesi, referansların null durumunu izler. İfade null değil veya belki null olabilir. Derleyici, bir değişkenin null olmadığını iki şekilde belirler:

  1. Değişkene, null olmadığı bilinen bir değer atanmıştır.
  2. Değişken null kontrol edildi ancak bu kontrol sonrası atanmadı.

Derleyicinin null olmayan olarak belirleyemediği tüm değişkenler belki-nullolarak kabul edilir. Analiz, yanlışlıkla bir null değer başvurusundan çıkarabileceğiniz durumlarda uyarılar sağlar. Derleyici, null durumuna göre uyarılar üretir.

  • Bir değişken null değilse, o değişkene güvenle referans alınabilir.
  • Bir değişken belki-null olduğunda, bu değişkenin başvuru kaldırılmadan önce null olmadığından emin olunması için denetlenmesi gerekir.

Aşağıdaki örneği inceleyin:

string? message = null;

// warning: dereference null.
Console.WriteLine($"The length of the message is {message.Length}");

var originalMessage = message;
message = "Hello, World!";

// No warning. Analysis determined "message" is not-null.
Console.WriteLine($"The length of the message is {message.Length}");

// warning!
Console.WriteLine(originalMessage.Length);

Önceki örnekte, ilk ileti yazdırıldığında derleyici message'nin belki-null olduğunu belirler. İkinci ileti için uyarı yok. Kodun son satırı null olabileceğinden originalMessage bir uyarı oluşturur. Aşağıdaki örnekte, düğüm ağacını köke geçirerek geçiş sırasında her düğümü işlemek için daha pratik bir kullanım gösterilmektedir:

void FindRoot(Node node, Action<Node> processNode)
{
    for (var current = node; current != null; current = current.Parent)
    {
        processNode(current);
    }
}

Üst kod, current değişkenine başvuramayla ilgili herhangi bir uyarı oluşturmaz. Statik analiz, current öğesinin belki-null olduğunda hiçbir zaman başvurulmadığını belirler. Değişken current, null karşı denetlenir current.Parent erişilmeden ve currentProcessNode eylemine gönderilmeden önce. Önceki örnekler, derleyicinin yerel değişkenlerin boş-durum durumunu nasıl belirlediğini, bunlar başlatıldığında, atandığında veya null ile karşılaştırıldığında gösterir.

Null durum analizi, çağrılan yöntemlere iz bırakmaz. Sonuç olarak, tüm oluşturucuların çağırdığı ortak bir yardımcı metoda başlatılan alanlar aşağıdaki iletiyle bir uyarı oluşturabilir:

Oluşturucudan çıkarken null değer atanamayan 'name' özelliği null olmayan bir değer içermelidir.

Bu uyarıları iki şekilde ele alabilirsiniz: Oluşturucu zincirleme veya yardımcı metoda ait null atanabilir öznitelikler. Aşağıdaki kodda her birinin bir örneği gösterilmektedir. Person sınıf, diğer tüm oluşturucular tarafından çağrılan ortak bir oluşturucu kullanır. Student sınıfında, System.Diagnostics.CodeAnalysis.MemberNotNullAttribute özniteliğiyle ek açıklamalı bir yardımcı yöntem bulunmaktadır.


using System.Diagnostics.CodeAnalysis;

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public Person() : this("John", "Doe") { }
}

public class Student : Person
{
    public string Major { get; set; }

    public Student(string firstName, string lastName, string major)
        : base(firstName, lastName)
    {
        SetMajor(major);
    }

    public Student(string firstName, string lastName) :
        base(firstName, lastName)
    {
        SetMajor();
    }

    public Student()
    {
        SetMajor();
    }

    [MemberNotNull(nameof(Major))]
    private void SetMajor(string? major = default)
    {
        Major = major ?? "Undeclared";
    }
}

Null atanabilir durum analizi ve derleyicinin oluşturduğu uyarılar, null'ün dereferans verilmesini önleyerek program hatalarını önlemenize yardımcı olur. Null atanabilir uyarıları çözme makalesi, kodunuzda büyük olasılıkla görülen uyarıları düzeltmeye yönelik teknikler sağlar. Null durum analizinden oluşturulan tanılamalar yalnızca uyarılardır.

API imzalarında öznitelikler

Null durum analizi, API'lerin semantiğini anlamak için geliştiricilerin ipuçlarına ihtiyaç duyar. Bazı API'ler null denetimleri sağlarlar ve bir değişkenin null durumunubelki-null yerine null-olmayan olarak değiştirmelidir. Diğer API'ler, giriş bağımsız değişkenlerinin null durumuna bağlı olarak null olmayan veya belki-null ifadeler döndürür. Örneğin, büyük harfle bir ileti görüntüleyen aşağıdaki kodu göz önünde bulundurun:

void PrintMessageUpper(string? message)
{
    if (!IsNull(message))
    {
        Console.WriteLine($"{DateTime.Now}: {message.ToUpper()}");
    }
}

bool IsNull(string? s) => s == null;

İncelemeye bağlı olarak, herhangi bir geliştirici bu kodu güvenli olarak değerlendirir ve uyarı oluşturmamalıdır. Ancak derleyici, IsNull null denetimi sağladığını bilmez ve message'yi belki-null bir değişken olarak kabul ederek message.ToUpper() deyimi için bir uyarı verir. Bu uyarıyı NotNullWhen düzeltmek için özniteliğini kullanın:

bool IsNull([NotNullWhen(false)] string? s) => s == null;

Bu öznitelik derleyiciye, eğer IsNullfalse dönerse, s parametresinin null olmadığını bildirir. Derleyici, message'ın if (!IsNull(message)) {...} bloğu içinde null durumu'u not-null olarak değiştirir. Uyarı verilmedi.

Öznitelikler, bağımsız değişkenlerin, dönüş değerlerinin ve bir üyenin çağrılması için kullanılan nesne örneğinin üyelerinin null durumları hakkında ayrıntılı bilgi sağlar. Her öznitelikle ilgili ayrıntılar, null atanabilir başvuru öznitelikleri hakkındaki dil başvuru makalesinde bulunabilir. .NET 5 itibarıyla tüm .NET çalışma zamanı API'lerine açıklama eklenir. Bağımsız değişkenlerin ve dönüş değerlerinin null durumu hakkında anlam bilgisi sağlamak için API'lerinize açıklama ekleyerek statik analizi geliştirirsiniz.

Null olabilen değişken açıklamaları

Null durum analizi, yerel değişkenler için güçlü analiz sağlar. Derleyicinin üye değişkenleri için sizden daha fazla bilgi alması gerekir. Derleyici, bir üyenin açılış köşeli ayracındaki tüm alanların null durumunu ayarlamak için daha fazla bilgiye ihtiyaç duyar. Erişilebilir oluşturuculardan herhangi biri nesneyi başlatmak için kullanılabilir. Bir üye alanı null olarak ayarlanabilir ise, derleyici, her yöntemin başında null durumunun belki de null olduğunu varsaymalıdır.

Bir değişkenin null atanabilir başvuru türü mü yoksa null atanamaz başvuru türümü olduğunu bildirebilen ek açıklamalar kullanırsınız. Bu ek açıklamalar, değişkenler için null durumu hakkında önemli açıklamalar yapar.

  • Bir referans null olmamalıdır. Null değer atanamayan başvuru değişkeninin varsayılan durumu null değildir. Derleyici, önce null olmadığını denetlemeden bu değişkenlere başvurmanın güvenli olmasını sağlayan kurallar uygular:
    • Değişkenin null olmayan bir değere başlatılması gerekir.
    • değişkenine hiçbir zaman değeri nullatanamıyor. Kod null olmaması gereken bir değişkene belki-null ifadesi atadığında derleyici bir uyarı döndürür.
  • Bir referans null olabilir. Null atanabilir bir başvuru değişkeninin varsayılan durumu belki null'dir. Derleyici, bir başvuruyu doğru şekilde null denetlediğinizden emin olmak için kuralları uygular.
    • Değişkenin işaretçi çözülerek değere erişilebilmesi için derleyicinin değerin nullolmadığını garanti edebilmesi gerekir.
    • Bu değişkenler varsayılan null değeriyle başlatılabilir ve diğer kodlarda null değer atanabilir.
    • Kod null olabilecek bir değişkene belki-null ifadesi atadığında derleyici uyarı vermez.

Herhangi bir null değer atanamayan başvuru değişkeninin null durumu başlangıçta null olmayan olarak ayarlanmıştır. Boş değer atanabilir her başvuru değişkeni, başlangıçta null durumu olarak belki-null durumundadır.

Null atanabilir başvuru türü, null atanabilir değer türleriyle aynı söz dizimi kullanılarak belirtilir: değişkenin türüne a ? eklenir. Örneğin, aşağıdaki değişken bildirimi null atanabilir dize değişkenini temsil eder: name

string? name;

Null atanabilir başvuru türleri etkinleştirildiğinde, tür adına eklenmeyen herhangi bir değişken ? null atanamaz bir başvuru türüdür. Bu özellik etkinleştirildikten sonra mevcut koddaki tüm başvuru türü değişkenlerini içerir. Ancak, var kullanılarak bildirilen örtük olarak yazılan tüm yerel değişkenler, null atanabilir başvuru türleridir. Önceki bölümlerde gösterildiği gibi, statik analiz yerel değişkenlerin null durumunu belirler ve başvurularını kaldırmadan önce belki null olup olmadıklarını belirler.

Bazen bir değişkenin null olmadığını bildiğiniz ancak derleyicinin null durumubelki-null olarak belirlediğinde uyarıyı geçersiz kılmanız gerekir. Değişken adının ardından null-forgiving işlecini kullanarak null durumunu null olmayan duruma zorlarsınız. Örneğin, değişkenin name olmadığını null ancak derleyicinin bir uyarı vermediğini biliyorsanız, derleyicinin çözümlemesini geçersiz kılmak için aşağıdaki kodu yazabilirsiniz:

name!.Length;

Null atanabilir başvuru türleri ve null atanabilir değer türleri benzer bir anlam kavramı sağlar: Bir değişken bir değeri veya nesneyi temsil edebilir veya bu değişken olabilir null. Ancak, null edilebilir başvuru türleri ve null edilebilir değer türleri farklı uygulanır: null edilebilir değer türleri System.Nullable<T> kullanılarak uygulanırken, null edilebilir başvuru türleri derleyici tarafından okunan öznitelikler aracılığıyla uygulanır. Örneğin, string? ve string her ikisi de aynı türle temsil edilir: System.String. Ancak, int? ve int sırasıyla System.Nullable<System.Int32> ve System.Int32 ile temsil edilir.

Boş değer atanabilir başvuru türleri bir derleme zamanı özelliğidir. Bu, çağıranların uyarıları yoksayıp, null olmayan bir başvuru bekleyen bir yöntemin bağımsız değişkeni olarak kasıtlı olarak null kullanabilecekleri anlamına gelir. Kütüphane yazarları, null bağımsız değişken değerlerine karşı çalışma zamanı denetimleri eklemelidir. ArgumentNullException.ThrowIfNull, çalışma zamanında bir parametreyi null değere karşı denetlemek için tercih edilen seçenektir. Ayrıca, null atanabilir ek açıklamaları kullanan bir programın çalışma zamanı davranışı, tüm null atanabilir ek açıklamalar (? ve !) kaldırılırsa aynı kalır. Tek amaçları tasarım amacını ifade etmek ve null durum analizi için bilgi sağlamaktır.

Önemli

Null atanabilir açıklamaların etkinleştirilmesi, Entity Framework Core'un bir veri üyesinin gerekli olup olmadığını belirleme biçimini değiştirebilir. Entity Framework Core Fundamentals: Working with Nullable Reference Types makalesinde daha fazla bilgi edinebilirsiniz.

Genel Türler

Genel değerler, herhangi bir tür parametresini işlemek için T?, ayrıntılı kurallar gerektirir T. Null atanabilir bir değer türü ve null atanabilir başvuru türü için geçmiş ve farklı uygulama nedeniyle kurallar mutlaka ayrıntılıdır. Nullable değer türleriSystem.Nullable<T> yapı kullanılarak gerçekleştirilir. Null atanabilir başvuru türleri , derleyiciye anlam kuralları sağlayan tür ek açıklamaları olarak uygulanır.

  • T için tür bağımsız değişkeni bir başvuru türüyse, T? karşılık gelen nullable başvuru türüne başvurur. Örneğin, bir T ise string, bir T? olur string?.
  • T için tür bağımsız değişkeni bir değer türüyse, T? aynı değer türünü T olarak referans alır. Örneğin, T bir int ise, T? de bir int olur.
  • T için tür bağımsız değişkeni null atanabilir bir başvuru türüyse, T? aynı null başvuru türüne başvurur. Örneğin, T bir string? ise, T? de bir string? olur.
  • T tür bağımsız değişkeni için null değer alabilen bir değer türüyse, T? de aynı null değer alabilen değer türüne başvurur. Örneğin, T bir int? ise, T? da bir int? olur.

Dönüş değerleri için T?, [MaybeNull]T ile eşdeğerdir; bağımsız değişken değerleri için T?, [AllowNull]T ile eşdeğerdir. Daha fazla bilgi için dil referansında null durum analizi üzerine öznitelikler makalesine bakın.

Kısıtlamaları kullanarak farklı davranışlar belirtebilirsiniz:

  • Kısıtlama, class öğesinin null değer alamayan bir başvuru türü (string gibi) olması gerektiği anlamına gelir. null atanabilir bir başvuru türü, örneğin string? için T kullanırsanız, derleyici bir uyarı üretir.
  • class? kısıtlaması, T'in ya null atanamaz bir başvuru türü (string) ya da null atanabilir bir başvuru türü (örneğin string?) olması gerektiği anlamına gelir. Tür parametresi string? gibi null atanabilir bir başvuru türü olduğunda, T? gibi bir ifade aynı null atanabilir başvuru türünü referans alır, string? örneğinde olduğu gibi.
  • Kısıtlama notnull, null atanamaz bir başvuru türü veya null atanamaz bir değer türü olması gerektiği anlamına gelir. Null yapılandırılabilir bir başvuru türü veya null yapılandırılabilir bir değer türünü tür parametresi olarak kullanırsanız, derleyici bir uyarı üretir. T bir değer türü olduğunda, döndürülen değer, karşılık gelen null atanabilir değer türü değil, bu değer türüdür.

Bu kısıtlamalar, derleyiciye nasıl T kullanıldığı hakkında daha fazla bilgi sağlamaya yardımcı olur. Bu, geliştiricilerin T için bir tür seçmesine yardımcı olur ve genel türün bir örneği kullanıldığında daha iyi bir null durumu analizi sağlar.

Null atanabilir bağlam

Null atanabilirlik bağlamı, null referans türü anotasyonlarının nasıl ele alınacağını ve hangi uyarıların statik null durum analizi tarafından üretileceğini belirler. Anullanabilir bağlam iki bayrak içerir: yorumlama ayarı ve uyarı ayarı.

Hem ek açıklama hem de uyarı ayarları mevcut projeler için varsayılan olarak devre dışı bırakılır. .NET 6'dan (C# 10) başlayarak her iki bayrak da yeni projeleri için varsayılan olarak etkinleştirilir. Nullable bağlam için iki ayrı işaret kullanılmasının nedeni, nullable başvuru türlerinin getirilmesinden önce var olan büyük projelerin geçişini kolaylaştırmaktır.

Küçük projeler için null atanabilir bağlantı türlerini etkinleştirebilir, uyarıları giderebilir ve devam edebilirsiniz. Ancak, daha büyük projeler ve çok projeli çözümler, çok sayıda uyarı üretebilir. Null atanabilir başvuru türlerini kullanmaya başladığınızda, bunları dosya bazında etkinleştirmek için pragmaları kullanabilirsiniz. System.NullReferenceException oluşturulmasına karşı koruma sağlayan yeni özellikler, mevcut bir kod tabanında etkinleştirildiğinde kesintiye neden olabilir.

  • Açıkça yazılan tüm başvuru değişkenleri null atanamayan başvuru türleri olarak yorumlanır.
  • Genel türlerdeki class kısıtlamasının anlamı, null atanamayan başvuru türü olacak şekilde değişti.
  • Bu yeni kurallar nedeniyle yeni uyarılar oluşturulur.

Derleyicinin davranışını, boş atanabilir ek açıklama bağlamı belirler. null durum ayarları için dört kombinasyon vardır.

  • her ikisi devre dışı: Kod null'a duyarsız. Devre dışı bırak seçeneği, yeni söz diziminin hatalar yerine uyarılar üretmesi dışında, null atanabilir başvuru türleri etkinleştirilmeden önceki davranışla eşleşir.
    • Nullable uyarıları kapatıldı.
    • Tüm referans türü değişkenleri null atanabilir referans türleridir.
    • ? eki, null atanabilir bir başvuru türü bildirmek için kullanıldığında bir uyarıya neden olur.
    • null forgiving işlecini kullanabilirsiniz, !ancak hiçbir etkisi yoktur.
  • ikisi de etkin: Derleyici, tüm null referans analizi ve tüm dil özellikleri etkin olarak ayarlar.
    • Tüm yeni null değer alabilir uyarılar etkinleştirilir.
    • ? ekini kullanarak null atanabilir bir başvuru türü bildirebilirsiniz.
    • Son eki olmayan ? başvuru türü değişkenleri null olmayan başvuru türleridir.
    • Null forgiving işleci, olası bir başvuru nullkaldırma için uyarıları bastırır.
  • uyarısı etkinleştirildi: Derleyici tüm null analizlerini gerçekleştirir ve kodun nullbaşvuru yapabileceği durumlarda uyarılar yayar.
    • Tüm yeni nullable uyarılar etkinleştirildi.
    • ? eki, null atanabilir başvuru türü olarak kullanıldığında uyarı verir.
    • Tüm başvuru türü değişkenlerinin null olması gerekir. Ancak, üyeler ? sonekiyle bildirilmedikçe, tüm yöntemlerin açılış küme ayracında null-olma durumu yerine değerli konumundadır.
    • null forgiving işlecini kullanabilirsiniz. !
  • açıklamalar etkin: Derleyici, kodun null başvurusunu kaldırabileceği veya null olabilecek bir ifadeyi null olamayan bir değişkene atadığınızda uyarı vermez.
    • Tüm yeni null değeri alabilen uyarılar devre dışı bırakıldı.
    • ? son ekini kullanarak null atanabilir bir başvuru türü bildirebilirsiniz.
    • Son ek içermeyen ? başvuru türü değişkenleri null olamayan başvuru türleridir.
    • null forgiving işlecini kullanabilirsiniz, !ancak hiçbir etkisi yoktur.

Null atanabilir ek açıklama bağlamı ve null atanabilir uyarı bağlamı, .csproj dosyanızda <Nullable> öğesini kullanarak bir proje için ayarlanabilir. Bu öğe, derleyicinin türlerin null atanabilirliğini nasıl yorumladığını ve hangi uyarıların verildiğini ayarlıyor. Aşağıdaki tabloda izin verilebilen değerler gösterilir ve bu değerlerin belirttiği bağlamlar özetler.

Bağlam Gönderme çözümleme uyarıları Atama uyarıları Referans türleri ? ek ! operatör
disable Devre Dışı Devre Dışı Tümü null atanabilir Uyarı oluşturur Etkisi yok
enable Aktif Etkinleştirildi "? ile bildirilmedikçe null atanamaz" Null olabilen türü bildirir Olası null atama için uyarıları gizler
warnings Etkinleştirildi Uygulanamaz Tümü null değer atanabilir, ancak metotların açılış küme ayracında üyeler null değilmiş gibi değerlendirilir. Uyarı oluşturur Olası null atama için uyarıları gizler
annotations Etkin Değil Devre Dışı "? ile belirtilmediği sürece null olamaz" Atanabilir null türü bildirir Etkisi yok

Devre dışı bırakılmış bir bağlamda derlenen koddaki başvuru türü değişkenleri, null atanabilir-belirsizdir. null sabit bir değer veya belki-null bir değişken, null'lığı önemsemeyen bir değişkene atanabilir. Ancak, bir nullable-oblivious değişkenin varsayılan durumu null olmayan halidir.

Projeniz için en uygun ayarı seçebilirsiniz:

  • Tanılamaya veya yeni özelliklere göre güncelleştirmek istemediğiniz eski projeler için devre dışı bırak'ı seçin.
  • Uyarıları seçerek kodunuzun nerede System.NullReferenceExceptionfırlatabileceğini belirleyin. Boş değer atanamayan başvuru türlerini etkinleştirmek için kodu değiştirmeden önce bu uyarıları ele alabilirsiniz.
  • Uyarıları etkinleştirmeden önce tasarım amacınızı ifade etmek için ek açıklamaları seçin.
  • Null referans istisnalarına karşı korumak istediğiniz yeni projeler ve aktif projeler için etkinleştir'i seçin.

Örnek:

<Nullable>enable</Nullable>

Bu bayrakları kaynak kodunuzun herhangi bir yerinde ayarlamak için yönergeleri de kullanabilirsiniz. Bu yönergeler en çok büyük bir kod tabanını geçirirken kullanışlıdır.

  • #nullable enable: Açıklama ve uyarı bayraklarını etkinleştir olarak ayarlar.
  • #nullable disable: Ek açıklama ve uyarı bayraklarını devre dışı bırakmak için ayarlar.
  • #nullable restore: Açıklama bayrağını ve uyarı bayrağını proje ayarlarına geri yükler.
  • :'yi devre dışı bırakmak için uyarı bayrağını ayarlayın.
  • :'yi etkinleştirmek için uyarı bayrağını olarak ayarlayın.
  • #nullable restore warnings: Uyarı bayrağını proje ayarlarına geri yükler.
  • #nullable disable annotations: Ek açıklama bayrağını devre dışı bırak olarak ayarlayın.
  • : Açıklama bayrağını etkinleştirmek için ayarlayın.
  • #nullable restore annotations: Not bayrağını proje ayarlarına geri yükler.

Herhangi bir kod satırı için aşağıdaki birleşimlerden herhangi birini ayarlayabilirsiniz:

Uyarı bayrağı Açıklama işareti Kullan
proje varsayılan proje varsayılanı Varsayılan
etkinleştirmek devre dışı bırak Analiz uyarılarını düzeltme
etkinleştirmek proje varsayılanı Analiz uyarılarını düzeltme
proje varsayılanı etkinleştirmek Tür ek açıklamaları ekleyin
etkinleştirmek etkinleştirmek Kod zaten taşındı
devre dışı bırak etkinleştirmek Uyarıları düzeltmeden önce koda ek açıklama ekleme
devre dışı bırak devre dışı bırak Geçirilen projeye eski kod ekleme
proje varsayılanı devre dışı bırak Nadiren
devre dışı bırak proje varsayılanı Nadiren

Bu dokuz birleşim, derleyicinin kodunuz için yaydığı tanılamalar üzerinde ayrıntılı denetim sağlar. Henüz ele almak için hazır olmadığınız daha fazla uyarı görmeden, güncelleştirdiğiniz herhangi bir alanda daha fazla özellik etkinleştirebilirsiniz.

Önemli

Genel null atanabilir bağlam, oluşturulan kod dosyaları için geçerli değildir. Her iki stratejide de, oluşturulduğu belirtilen kaynak dosyalar için null bırakılabilir bağlam devre dışı bırakılır. Bu, oluşturulan dosyalardaki API'lere açıklama eklenmediği anlamına gelir. Oluşturulan dosyalar için null değer uyarısı oluşturulmaz. Bir dosyanın oluşturuldu olarak işaretlenmesinin dört yolu vardır:

  1. .editorconfig dosyasında, ilgili dosyaya uygulanan bir bölümde generated_code = true belirleyin.
  2. Dosyanın en üstüne bir açıklama olarak <auto-generated> veya <auto-generated/> ekleyin. Bu açıklamadaki herhangi bir satırda olabilir, ancak açıklama bloğu dosyadaki ilk öğe olmalıdır.
  3. Dosya adını TemporaryGeneratedFile_ ile başlatma
  4. Dosya adını .designer.cs, .generated.cs, .g.cs veya .g.i.cs ile sonlandırın.

Oluşturucular ön işlemci yönergesini #nullable kullanarak kabul edebilir.

Varsayılan olarak, nullable ek açıklama ve uyarı bayrakları devre dışı. Bu, mevcut kodunuzun değişiklik yapmadan ve yeni uyarı oluşturmadan derlenmesi anlamına gelir. .NET 6 ile başlayarak, yeni projeler tüm proje şablonlarındaki öğesini içerir ve bu bayrakları etkinolarak ayarlar.

Bu seçenekler, mevcut bir kod tabanını null atanabilir başvuru türlerini kullanmaya uygun hale getirmek için iki farklı strateji sunar.

Bilinen tuzaklar

Başvuru türleri içeren diziler ve yapılar, null atanabilir başvurularda ve null güvenliği belirleyen statik analizde bilinen tuzaklardır. Her iki durumda da, null atanamaz bir başvuru null ile başlatılabilir ve uyarı oluşturmadan.

Yapılar

Null atanamayan başvuru türleri içeren bir yapı, herhangi bir uyarıya neden olmadan default atanmasına izin verir. Aşağıdaki örneği inceleyin:

using System;

#nullable enable

public struct Student
{
    public string FirstName;
    public string? MiddleName;
    public string LastName;
}

public static class Program
{
    public static void PrintStudent(Student student)
    {
        Console.WriteLine($"First name: {student.FirstName.ToUpper()}");
        Console.WriteLine($"Middle name: {student.MiddleName?.ToUpper()}");
        Console.WriteLine($"Last name: {student.LastName.ToUpper()}");
    }

    public static void Main() => PrintStudent(default);
}

Önceki örnekte, null atanamaz başvuru türleri FirstName ve LastName null iken PrintStudent(default) içinde bir uyarı yoktur.

Daha yaygın bir diğer durum da genel yapılarla ilgilenmenizdir. Aşağıdaki örneği inceleyin:

#nullable enable

public struct S<T>
{
    public T Prop { get; set; }
}

public static class Program
{
    public static void Main()
    {
        string s = default(S<string>).Prop;
    }
}

Önceki örnekte özelliği Prop çalışma zamanında null olarak bulunur. Null atanamayan bir dizeye, herhangi bir uyarı olmadan atanır.

Diziler

Diziler, null atanabilir başvuru türlerinde de bilinen bir tuzaktır. Hiçbir uyarı üretmeyen aşağıdaki örneği göz önünde bulundurun:

using System;

#nullable enable

public static class Program
{
    public static void Main()
    {
        string[] values = new string[10];
        string s = values[0];
        Console.WriteLine(s.ToUpper());
    }
}

Önde gelen örnekte, dizinin bildirimi, null olamayan dizeler içerdiğini gösterirken, öğelerinin tümü null'ya başlatılır. Ardından değişkene s bir null değer (dizinin ilk öğesi) atanır. Son olarak, değişken s başvuru çözülür ve bu da bir çalışma zamanı hatasına neden olur.

Kurucular

Bir sınıfın oluşturucusu, o oluşturucu tarafından bir hata durumu meydana geldiğinde bile sonlandırıcıyı çağırmaya devam eder.
Aşağıdaki örnekte bu davranış gösterilmektedir:

public class A
{
    private string _name;
    private B _b;

    public A(string name)
    {
        ArgumentNullException.ThrowIfNullOrEmpty(name);
        _name = name;
        _b = new B();
    }

  ~A()
  {
      Dispose();
  }

  public void Dispose()
  {
      _b.Dispose();
      GC.SuppressFinalize(this);
  }
}

public class B: IDisposable
{
    public void Dispose() { }
}

public void Main()
{
    var a = new A(string.Empty);
}

Yukarıdaki örnekte, name parametresi nullise _b.Dispose(); çalıştırıldığında System.NullReferenceException oluşturulur. Oluşturucu başarıyla tamamlandığında, _b.Dispose(); çağrısı asla bir hata oluşturmaz. Derleyici tarafından uyarı verilmedi, çünkü statik analiz bir yöntemin (oluşturucu gibi) çalışma zamanında bir istisna fırlatılmadan tamamlanıp tamamlanmadığını belirleyemez.

Ayrıca bkz.