Null atanabilirliği anlama
.NET geliştiricisiyseniz, büyük olasılıkla ile karşılaşmışsınızdır System.NullReferenceException. Bu, çalışma zamanında bir başvurulmadığında null , yani bir değişken çalışma zamanında değerlendirildiğinde, ancak değişkenine nullbaşvurduğunda oluşur. Bu özel durum açık arayla .NET ekosisteminde en sık karşılaşılan özel durumdur. Sör Tony Hoare'nin yaratıcısı null"milyar dolarlık hata" olarak adlandırılır null .
Aşağıdaki örnekte değişkenine FooBar atanır null ve hemen başvurulmaz ve bu nedenle sorun sergilenir:
// Declare variable and assign it as null.
FooBar fooBar = null;
// Dereference variable by calling ToString.
// This will throw a NullReferenceException.
_ = fooBar.ToString();
// The FooBar type definition.
record FooBar(int Id, string Name);
Uygulamalarınızın boyutu ve karmaşıklığı arttığında sorun geliştirici olarak fark etmek çok daha zor hale gelir. Bunun gibi olası hataları tespit etmek bir araç işidir ve C# derleyicisi yardımcı olmak için buradadır.
Null güvenlik tanımlama
Null güvenlik terimi, olası oluşum sayısını azaltmaya yardımcı olan NullReferenceException özgü bir özellik kümesini tanımlar.
Önceki FooBar örneği göz önünde bulundurarak değişkenin NullReferenceException başvuruyu fooBar kaldırmadan önce olup olmadığını null denetleyerek öğesini önleyebilirsiniz:
// Declare variable and assign it as null.
FooBar fooBar = null;
// Check for null
if (fooBar is not null)
{
_ = fooBar.ToString();
}
// The FooBar type definition for example.
record FooBar(int Id, string Name);
Derleyici, bunun gibi senaryoların tanımlanmasına yardımcı olmak için kodunuzun amacını çıkarsayarak istenen davranışı uygulayabilir. Ancak, bu yalnızca null değeri alabilir bir bağlam etkinleştirildiğinde olur. Null atanabilir bağlamı tartışmadan önce, olası null atanabilir türleri açıklayalım.
Boş değer atanabilir tipler
C# 2.0'da yalnızca başvuru türleri null atanabilirdi. gibi int veya DateTime değer türleri olamazdınull. Bu türler bir değer olmadan başlatılırsa, değerlerine default geri dönerler. durumunda int, bu olur 0.
DateTimebir için, bu DateTime.MinValue.
Başlangıç değerleri olmadan örnek olarak örneklene başvuru türleri farklı çalışır. Tüm başvuru türlerinin default değeri olur null.
Aşağıdaki C# kod parçacığını göz önünde bulundurun:
string first; // first is null
string second = string.Empty // second is not null, instead it's an empty string ""
int third; // third is 0 because int is a value type
DateTime date; // date is DateTime.MinValue
Yukarıdaki örnekte:
-
firstbununnullnedeni, başvuru türününstringbildirildiği ancak atama yapılmadığıdır. -
secondbildirildiğinde atanırstring.Empty. Nesnenin hiç atamasınullolmadı. -
thirdatanmamış olmasına0rağmen. Bu birstruct(değer türü) ve değerinedefaultsahiptir0. -
datebaşlatılmamış, ancakdefaultdeğeri şeklindedir System.DateTime.MinValue.
C# 2.0'dan başlayarak, kullanarak (veya kısaltma için) null atanabilir değer türleri Nullable<T>T?. Bu, değer türlerinin null atanabilir olmasını sağlar. Aşağıdaki C# kod parçacığını göz önünde bulundurun:
int? first; // first is implicitly null (uninitialized)
int? second = null; // second is explicitly null
int? third = default; // third is null as the default value for Nullable<Int32> is null
int? fourth = new(); // fourth is 0, since new calls the nullable constructor
Yukarıdaki örnekte:
-
first,nullnull atanabilir değer türünün başlatılmamış olmasıdır. -
secondbildirildiğinde atanırnull. -
thirddeğeri olaraknulldefaultNullable<int>değeridir.null -
fourth,0ifadeninnew()oluşturucuyu çağırdığıNullable<int>veintvarsayılan olarak olduğu şekildedir0.
C# 8.0, bir başvuru türünün veya her zaman olmayan bir başvuru türünün "Tüm başvuru türlerinin null atanabilir olduğunu düşünmüştüm!" diye düşünüyor olabilirsiniz. Sen haksız değilsin, onlar da. Bu özellik, derleyicinin zorlamaya çalıştığı amacınızı ifade etmenizi sağlar. Aynı T? söz dizimi, başvuru türünün null atanabilir olmasını hedeflediğini ifade eder.
Aşağıdaki C# kod parçacığını göz önünde bulundurun:
#nullable enable
string first = string.Empty;
string second;
string? third;
Yukarıdaki örnekte, derleyici amacınızı aşağıdaki gibi çıkarsar:
-
firstaslanulldeğildir, çünkü kesinlikle atanmıştır. -
secondolmamalıdırnull.secondDeğer atamadan önce değerlendirme, başlatılmamış olduğundan derleyici uyarısıyla sonuçlanır. -
thirdolabilirnull. Örneğin, , ancakSystem.String. Bu varyasyonlardan herhangi biri kabul edilebilir. Derleyici, önce null olmadığını denetlemeden başvuruyuthirdgeri alırsanız sizi uyararak size yardımcı olur.
Önemli
Yukarıda gösterildiği gibi null atanabilir başvuru türleri özelliğini kullanmak için, null atanabilir bir bağlam içinde olmalıdır. Bu, sonraki bölümde ayrıntılı olarak anlatılır.
Boş değer atanabilir bağlam
Null atanabilir bağlamlar, derleyicinin başvuru türü değişkenlerini nasıl yorumlayabilmesi için ayrıntılı denetim sağlar. Dört olası null atanabilir bağlam vardır:
-
disable: Derleyici, C# 7.3 ve önceki sürümlere benzer şekilde davranır. -
enable: Derleyici tüm null başvuru analizini ve tüm dil özelliklerini etkinleştirir. -
warnings: Derleyici tüm null çözümlemelerini gerçekleştirir ve kodun başvuruyunullkaldırabileceği durumlarda uyarı verir. -
annotations: Derleyici, kodun başvuruyu kaldırabileceğinulldurumlarda null çözümleme gerçekleştirmez veya uyarı göndermez, ancak yine de null atanabilir başvuru türlerini?ve null-forgiving işleçlerini (!) kullanarak kodunuz için açıklama ekleyebilirsiniz.
Bu modülün kapsamı ya da disableenable null atanabilir bağlamlar olarak belirlenmiştir. Daha fazla bilgi için Null atanabilir başvuru türlerine başvurun: Null atanabilir bağlamlar.
Boş değer atanabilir başvuru türlerini etkinleştirme
C# proje dosyası (.csproj) içinde, <Nullable> öğesine bir alt <Project> düğüm ekleyin (veya var olan <PropertyGroup> bir düğüme ekleyin). Bu, null atanabilir bağlamı enable projenin tamamına uygular.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- Omitted for brevity -->
</Project>
Alternatif olarak, derleyici yönergesini kullanarak null atanabilir bağlamı bir C# dosyasıyla sınırlayabilirsiniz.
#nullable enable
Yukarıdaki C# derleyici yönergesi işlevsel olarak proje yapılandırmasına eşdeğerdir, ancak kapsamı içinde bulunduğu dosyayla belirlenmiştir. Daha fazla bilgi için bkz Null başvuru türleri: Boş değer atanabilir bağlamlar (belgeler)
Önemli
.NET 6.0 ve üzeri ile başlayan tüm C# proje şablonlarında, .csproj dosyasında null atanabilir bağlam varsayılan olarak etkinleştirilir.
Boş değer atanabilir bağlam etkinleştirildiğinde yeni uyarılar alırsınız. Null değer atanabilir bir bağlamda analiz edildiğinde iki uyarı içeren önceki FooBar örneği göz önünde bulundurun:
FooBar fooBar = null;satırınınnullatamasında bir uyarı var: C# Uyarısı CS8600: Null literal veya olası null değeri, atanamaz türde dönüştürülüyor.Satırda
_ = fooBar.ToString();da bir uyarı vardır. Derleyici bu kezfooBarnull olabileceğinden endişe ediyor: C# Uyarısı CS8602: Muhtemelen null bir başvurunun dereferansı.
Önemli
Tüm uyarılara tepki verirseniz ve bunları ortadan kaldırsanız bile garantili null güvenlik yoktur. Derleyicinin çözümlemesini geçirecek ancak çalışma zamanıyla NullReferenceExceptionsonuçlanacak bazı sınırlı senaryolar vardır.
Özet
Bu ünitede, C# dilinde boş değer atanabilir bir bağlamı etkinleştirerek karşı NullReferenceExceptionkorumaya yardımcı olduğunu öğrendiniz. Sonraki ünitede amacınızı boş değer atanabilir bir bağlamda açıkça ifade etme hakkında daha fazla bilgi edineceksiniz.