CodeGym /Kurslar /C# SELF /Nullable Reference Types-ə giriş

Nullable Reference Types-ə giriş

C# SELF
Səviyyə, Dərs
Mövcuddur

1. NullReferenceException problemi

Demək olar ki, hər bir yeni başlayan (və təkcə onlar yox) C# proqramçısı bu qorxulu mesajla ən azı bir dəfə qarşılaşıb:


System.NullReferenceException: Obyekt referansı obyektin instansiyasına təyin edilməyib.

Budur, klassik bir nümunə:

string salam = null;
Console.WriteLine(salam.Length); // BAM! NullReferenceException

Məna sadədir: sən mövcud olmayan obyektə müraciət etməyə çalışırsan. Yəni dəyişən null-a işarə edir — obyektin yerinə boşluq.

Niyə bu səhvi etmək asandır?

Çünki C#-da əksər referans tipləri tarixən null ala bilirdi. Proqramçılar çox vaxt dəyişənin həqiqətən obyektə işarə etdiyini yoxlamağı unudurdular və nəticədə məşhur NullReferenceException alırdılar.

Əgər proqramçı hər NullReferenceException üçün bir dollar alsaydı, çoxdan öz əməliyyat sistemini yazardı.

Bu niyə problemdir?

Əvvəl öyrəndik ki, int? və ya double? kimi tiplər null ola bilər — yəni "dəyər yoxdur" vəziyyətini açıq göstərmək üçün (məsələn, bazada sahə boş ola bilər).

Ancaq referans tipləri (məsələn, string, istənilən class-lar, massivlər və s.) həmişə null ola bilərdi. Bu, C# yaranandan belədir. Rahatdır, amma təhlükəlidir — çünki dil səni məcbur etmirdi ki, "Bəlkə bu referans boşdur?" deyə düşünəsən.

2. İnkişaf: Nullable Reference Types (NRT)

5 il əvvəl bir yenilik təqdim olundu ki, NullReferenceException ilə mübarizəyə tam fərqli yanaşma gətirdi — Nullable Reference Types (NRT).

string s = "salam";   // not-nullable reference
string? bəlkə = null; // nullable reference
Not-nullable və nullable referans tipləri arasındakı fərq

Əsas ideya:

  • Heç vaxt null ola bilməyən referans dəyişənləri, null ola bilənlərdən sərt şəkildə ayırmaq.
  • Proqramçıya null ilə bağlı potensial problemləri artıq compile zamanı göstərmək, yoxsa runtime-da (artıq gec olanda) yox.

Yeni C# versiyalarında referans dəyişənlərin elanına yanaşma dəyişib: default olaraq null təyin etmək olmaz, yalnız sən açıq şəkildə icazə vermisənsə.

Çox sadə — cəmi bir ? simvolu, amma dəyişənin mənası dərhal dəyişir!

3. Nullable Reference Types-i aktivləşdirmək

Default olaraq bu ciddi sintaksis əksər proyektlərdə deaktivdir, köhnə kodu pozmamaq üçün. Amma müasir Visual Studio, Rider və .NET CLI şablonları artıq NRT ilə gəlir — ya da ən azı bunu tövsiyə edir.

Layihəndə NRT aktivdir ya yox, bunu bilmək üçün .csproj faylında bu sətri tap:

<Nullable>enable</Nullable>
Layihədə NRT-ni aktiv etmək

Əgər bu sətir yoxdursa, özün əlavə edə bilərsən — təhlükəsizdir.

Bu kodu necə dəyişir?

  • NRT deaktivdirsə (köhnə davranış): string s = null; — heç bir səhv yoxdur, hamı razıdır.
  • Aktivdirsə: compiler əsəbləşəcək, əgər null təyin etməyə çalışırsansa ora ki, null olmamalıdır.

4. NRT ilə nümunələr

Sadə nümunə


#nullable enable // Bu sətr bu faylda NRT yoxlamasını aktiv edir

string notNullable = "Salam";
string notNullable2 = null; // KOMPİLYASİYA SƏHVi!
string? nullableString = null; // Problem yoxdur, açıq şəkildə null icazə verdik
null-a qarşı ciddi yoxlama nümunəsi

Birinci sətrdə obyektə həmişə işarə edən string elan etdik.
Üçüncü sətrdə isə null ola bilən string elan etdik.

null-a yoxlama

void PrintLength(string? s)
{
    // Compiler deyəcək: "Bəs s == null olsa?"
    Console.WriteLine(s.Length); 
    
    // Belə - yaxşıdır
    if (s != null)
    {
        Console.WriteLine(s.Length); 
    }
}

Compiler artıq yoxlamaları unutmağa qoymur!

Compiler xəbərdarlıqları

Əgər xəbərdarlığı saymasan və yenə də nullable dəyişənə yoxlamasız müraciət etsən — yeni (çox faydalı!) compiler xəbərdarlığı alacaqsan. Bu səhv deyil (proqram yenə də build olacaq), amma sarı "lampa" deyir: "Əminsən, dostum?"

Rejimləri müqayisə edirik:

C# tipi Null ola bilər? Legacy rejimi (NRT-dən əvvəl) NRT rejimi (#nullable enable)
int Xeyr Xeyr Xeyr
int? Bəli Bəli Bəli
string Bəli Xeyr (həmişə olar) Xeyr (default olaraq olmaz)
string? Bəli Xeyr Bəli

5. Məsləhətlər: NRT-ni necə və niyə istifadə etməli

  • Bug-ların azalması: null səbəbindən gözlənilməz crash-lar azalır, developer və istifadəçi üçün daha çox sevinc.
  • Kodun aydınlığı: Dərhal görünür ki, nə boş ola bilər, nə isə həmişə dolu olmalıdır.
  • Compiler köməyi: Etiraf edək — o, həqiqətən bizim üçün çalışır! NRT xəbərdarlıqları potensial səhvlər barədə dəyərli məlumatdır.

Harada əvəzolunmazdır

  • Böyük layihələrdə, bir neçə nəfər eyni kod üzərində işləyirsə.
  • API və public kitabxanalarda — başqalarına nə etmək olar, nə olmaz göstərmək üçün.
  • Etibarlılıq vacibdirsə (məsələn, bank tətbiqləri, tibb sistemləri və s.)

6. Tipik səhvlər və tələlər

  • "? qoymağı unutdum"
    Adi string-ə null təyin edirsən (string s = null;) — compiler əsəbləşir, çünki default olaraq adi string null olmamalıdır.
  • "? ilə həddini aşdım"
    Compiler susmaq üçün bütün dəyişənləri string? edirsən. Məqsəd odur ki, harada həqiqətən boşluq ola bilər, onu diqqətlə işarələyəsən.
  • "Xəbərdarlığı səhv başa düşdüm"
    Xəbərdarlığı saymırsan, sonra NullReferenceException alırsan, halbuki compiler səni qoruyacaqdı.
2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
Nullable Reference Types elan edilməsi
Nullable Reference Types elan edilməsi
2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
Null üçün yoxlama
Null üçün yoxlama
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION