CodeGym /Kurslar /C# SELF /Avtomatik property-lər və init-only setter-lər

Avtomatik property-lər və init-only setter-lər

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

1. Avtomatik property-lər

C#-da property-lər (property) — sahə (field) və metod arasında bir şeydir. Əslində, bu, sintaktik şəkərdir, hansı ki, kapsulyasiya ilə işləməyi maksimum rahat edir. Sən property-ə elə müraciət edirsən ki, guya bu, adi sahədir, amma içəridə istənilən məntiq ola bilər: data yoxlaması, başqa sahələrin dəyişməsi, metodların çağırılması, hətta nənənə e-mail göndərmək (sonuncunu məsləhət görmürəm). Keçən dərsdə property-ləri əl ilə yazırdıq. Amma bu tez bezdirici olur, əgər səndə 100500 sadə obyekt varsa və yalnız "getter" və "setter" lazımdır — heç bir xüsusi məntiq olmadan.

Qarşıla — avtomatik property-lər. Onlar səni şablon koddan xilas edəcək və C#-a dəyərin saxlanmasını həvalə edəcək.

Əvvəl necə idi: əl ilə property-lər

Əgər sahəni gizlətmək, amma ona property vasitəsilə çıxış vermək istəyirik, adətən belə yazırıq:


public class Dog
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}
Private sahə ilə əl property-si

Belə kod — tipik "zanudluq" (boilerplate). Çox vaxt bu get/set-lərə heç nə "əlavə etmək" lazım olmur! Sadəcə çıxış vermək — vəssalam.

İndi necə etmək olar

C#-da hər şey daha asan oldu: artıq sahələri əl ilə yazmağa ehtiyac yoxdur — bunu compiler özü həll edir. Sadəcə belə yazırsan:


public class Dog
{
    public string Name { get; set; }
}
Avtomatik property

Vəssalam. Name dəyərini rahatlıqla oxuya və dəyişə bilərsən, arxa planda isə compiler özü private sahə yaradır, hansı ki, birbaşa çöl tərəfdən çıxış yoxdur.

Əslində arxa planda nə baş verir? Koddakı public string Name { get; set; } görən kimi, compiler avtomatik olaraq Name__BackingField kimi gizli sahə yaradır. Name-ə hər müraciətdə lazım olan getter və ya setter-i əlavə edir. Sahə birbaşa kodda görünmür, amma mövcuddur — hətta reflection ilə onu tapmaq da olar (amma bu artıq başqa hekayədir).

Belə yanaşmanın nəyi yaxşıdır? Birincisi, çox qısadır və eyni şeyi təkrar yazmağa ehtiyac yoxdur. İkincisi, kod daha təmiz olur: az vizual səs-küy, oxumaq və dəstəkləmək asandır. Və nəhayət, bu daha təhlükəsizdir — heç kim sahələrə birbaşa müdaxilə edə bilmir, çıxış yalnız property-lər vasitəsilədir.

2. Avtomatik property-lərin sintaksisi

Sintaksis çox sadədir:


public class Dog
{
    public string Name { get; set; }
    public int Age { get; set; }
}
Bir neçə avtomatik property

İndi bizim Dog daha yığcam görünür! Obyektləri belə yarada və dəyərləri rahatlıqla verə bilərik:

Dog myDog = new Dog();
myDog.Name = "Barbos";
myDog.Age = 4;

Qısa sxem

Yanaşma Sintaksis Dəyərə çıxış
Sahə
public string Name;
Birbaşa çıxış
Əl property-si
public string Name { get; set; } + private string name;
get/set vasitəsilə çıxış
Avtomatik property
public string Name { get; set; }
get/set + gizli sahə

3. Çıxışın fərdiləşdirilməsi: yalnız oxumaq, yalnız yazmaq

Yalnız oxumaq üçün: get-only

Əgər property-ni yalnız oxumaq lazımdırsa (məsələn, heyvanın qeydiyyat nömrəsi), onu yalnız oxumaq üçün edə bilərsən — get yazırsan, set isə ya heç yazılmır, ya da private olur. Belə dəyəri yalnız konstruktor və ya birbaşa elan zamanı vermək olar:


public class Dog
{
    public string RegistrationCode { get; }

    public Dog()
    {
        RegistrationCode = "DOG-001"; // Konstruktor zamanı dəyər veririk
    }
}

İndi çöldən yalnız RegistrationCode-u oxumaq olar, dəyişmək mümkün deyil. Vacib datanı təsadüfi dəyişikliklərdən qorumaq üçün əla üsuldur.

Başqa variant: private set


public string Name { get; private set; }
Private setter — yalnız class daxilində dəyişmək olar

Belə olduqda property-ni yalnız class daxilində dəyişmək olar (məsələn, metod və ya konstruktor vasitəsilə).

Yalnız yazmaq üçün: pis fikir

Teorik olaraq set-only property (yalnız yazmaq üçün) etmək olar, amma bu çox nadir hallarda istifadə olunur və məsləhət deyil — təsəvvür et, obyekt "qara dəlik" kimi davranır: ora nəsə atırsan, amma geri almaq — heç vaxt.

4. init-only setter-lər

Bir az tarixçə

Əvvəllər dəyişməz obyekt (immutable) yaratmaq üçün yalnız get property-ləri yazırdıq və dəyərləri konstruktor vasitəsilə verirdik. OK, rahatdır — amma həmişə yox. Amma yaxınlarda C#-da yeni sintaksis gəldi: init-only property-lər.

init-setter-in mahiyyəti nədir?

  • Dəyəri yalnız obyekt yaradılarkən təyin etməyə imkan verir (yəni konstruktor və ya obyekt initializer-də).
  • Obyekt yaradıldıqdan sonra property yalnız oxumaq üçün olur.
  • "Demək olar ki, dəyişməz" class-lar, DTO, konfiqurasiyalar, modellər üçün əladır.

public class Dog
{
    public string Name { get; init; }
    public int Age { get; init; }
}
init-setter-lə property-lər

İndi belə edə bilərik:

Dog dog = new Dog { Name = "Bobik", Age = 2 };
dog.Name = "Rəks"; // Səhv! Yaradıldıqdan sonra — yalnız oxumaq

Konstruktor vasitəsilə də dəyər vermək olar:

public Dog(string name, int age)
{
    Name = name;
    Age = age;
}

Sxem: nə vaxt dəyər vermək olar

Harada dəyər vermək olar? { get; set; } { get; private set; } { get; init; }
Class-dan kənarda, yaradıldıqdan sonra ✅ ❌ ❌
Konstruktor-da ✅ ✅ ✅
Initializer-də ✅ ❌ ✅
Class daxilində ✅ ✅ ❌ (konstruktor istisna olmaqla)

5. Praktikada tətbiqi

Gəlin Dog class-ımızı avtomatik və init-only property-lərlə yenidən yazaq:


public class Dog
{
    // Yalnız initialization zamanı təyin olunan property
    public string Name { get; init; }
    public int Age { get; init; }

    // Cari vəziyyət üçün avtomatik property
    public bool IsHungry { get; set; }

    // Dog-un hərəkətləri üçün metod
    public void Bark()
    {
        Console.WriteLine($"{Name} deyir: Hav!");
    }
}

İndi Dog belə yarada bilərik:

Dog dog = new Dog { Name = "Şarik", Age = 3, IsHungry = true };

dog.Bark(); // çıxacaq: Şarik deyir: Hav!
dog.IsHungry = false; // bu property-ni yaradıldıqdan sonra dəyişmək olar
dog.Name = "Barbos"; // Səhv! Property yalnız initialization üçündür

6. Başlanğıc dəyərlə avtomatik property-lər

C#-da hər şey sənin rahatlığın üçündür. Hətta property-yə birbaşa başlanğıc dəyər də vermək olar:


public class Dog
{
    public string Name { get; set; } = "Adsız";
    public int Age { get; set; } = 0;
}
Başlanğıc dəyərlə avtomatik property-lər

Və ya init ilə:


public class Dog
{
    public string Name { get; init; } = "Şən";
    public int Age { get; init; } = 0;
}
Başlanğıc dəyərlə init-only property-lər

İndi əgər Name yaradılarkən verilməsə, default olaraq "Şən" olacaq.

7. Müxtəlif səviyyəli çıxışla avtomatik property-lər

Property-ni elə etmək olar ki, oxumaq və yazmaq üçün fərqli access modifier-lər olsun:


public class Dog
{
    public string Name { get; private set; }
    public int Age { get; private set; }
    
    public Dog(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

Bu halda adı və yaşı yalnız Dog class-ı daxilində dəyişmək olar, məsələn, metod və ya konstruktor vasitəsilə.

Əl və avtomatik property-lərin müqayisəsi

Yanaşma Yazmaq çətinliyi set/get-də nəzarət Yaradıldıqdan sonra dəyişmək Modellərdə istifadə
Əl property-si Uzun Absolyut İstənilən Məntiq lazım olanda
Avtomatik property Qısa Yoxdur İstənilən və ya private Demək olar ki, hər yerdə
init-only avtomatik Qısa Yoxdur Yalnız yaradılarkən DTO, config-lər

8. Property-lərlə işləyərkən tipik səhvlər

Səhv №1: get-only property-yə konstruktor-dan kənarda dəyər verməyə cəhd.
Əgər property yalnız get ilə elan olunubsa, compiler başqa yerdə ona dəyər verməyə imkan verməyəcək. Yalnız konstruktor və ya birbaşa elan zamanı dəyər vermək olar. Unutsan — compilation error alacaqsan.

Səhv №2: sahə ilə property-ni qarışdırmaq.
Adi sahəni avtomatik property ilə əvəz edəndə, kodun başqa yerlərində birbaşa sahəyə müraciət qalmadığına əmin ol. Sahə və property fərqli şeylərdir və köhnə müraciətlər qalsa, compiler ya səhv verəcək, ya da proqram gözlənilməz davranacaq.

Səhv №3: private set-in nəticələrini anlamadan istifadə.
Əgər property-də private set varsa, amma başqa kodda ona dəyər verməyə cəhd edirlərsə — səhv olacaq. Bu, çox vaxt təsadüfən baş verir, xüsusilə başqasının kodunu kopyalayanda. Həmişə yoxla ki, set istifadə etmək istədiyin yerdə açıqdırmı.

2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
Yalnız init ilə təyin olunan xüsusiyyətlərdən istifadə
Yalnız init ilə təyin olunan xüsusiyyətlərdən istifadə
2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
Başlanğıc dəyərlərlə avtomatik xassələr
Başlanğıc dəyərlərlə avtomatik xassələr
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION