1. Giriş
Gəlin birbaşa field-lərdən istifadə zamanı yaranan problemlərlə başlayaq. Əgər sən bir field-i public kimi elan etsən, onu proqramın istənilən yerindən birbaşa dəyişmək olar:
public class Dog
{
public string Name;
}
Dog dog = new Dog();
dog.Name = ""; // O_o ... bu, "itin adı = boş sətir" deməkdir!
İstifadəçi Name field-inə tamamilə absurd dəyərlər verə bilər, məsələn, boş sətir, çox uzun ad və ya ümumiyyətlə null. Bu elə bil ki, sən yeni IKEA şkafını yığmaq istəyirsən, amma kimsə sənə bütün mebel zavoduna giriş verir.
Xatırladıram ki, inkapsulyasiya — obyektin öz məlumatlarını özü idarə etməsidir. Biz daxili hissələri hər gələnə etibar etmirik, xüsusi "qapılar" — xüsusiyyətlər (Properties) veririk, məhz onlar vasitəsilə field-ə giriş olur, amma yoxlama, loglama, dəyişiklik və ya başqa reaksiyalar əlavə etmək imkanı ilə.
2. Tərif və sintaksis
Property — class-ın xüsusi üzvüdür, görünüşcə field-ə bənzəyir, amma əslində arxada iki xüsusi metoddan ibarətdir: getter (dəyəri almaq) və setter (dəyəri təyin etmək). Property ilə biz:
- Məlumatların oxunmasına/yazılmasına icazə verə və ya qadağa qoya bilərik;
- Məlumatlara giriş zamanı validasiya və ya məntiq əlavə edə bilərik;
- Daxili field-i gizlədə və hətta dəyəri başqa yerdə saxlaya bilərik.
Property elan etmək field-ə çox bənzəyir, sadəcə curly braces və içəridə get və set açar sözləri ilə.
[giriş_modifikatoru] tip PropertyAdi
{
get { ... }
set { ... }
}
Bizim Dog class-ı üçün nümunə:
public class Dog
{
private string _name; // daxili field (private!)
public string Name
{
get { return _name; } // "getter": adı al
set { _name = value; } // "setter": adı təyin et
}
}
Qeyd: alt xətt adətən private field-lər üçün istifadə olunur (_name). Bu, C# stil standartıdır.
3. Property-nin işləmə mexanikası
Property — obyektin daxili məlumatları ilə xarici dünya arasında bir növ "mühafizəçi"dir. Nümunə:
Dog dog = new Dog();
dog.Name = "Şarik";
Console.WriteLine(dog.Name);
İzah:
- Proqram icrası dog.Name = "Şarik"; sətrinə çatanda — həmin anda property-nin set metodu çağırılır və sən ora istənilən yoxlama əlavə edə bilərsən (məsələn, ad boş olmasın deyə).
- Console.WriteLine(dog.Name); zamanı isə get metodu çağırılır, o ya cari dəyəri qaytarır, ya da lazım olsa, dinamik hesablama aparır.
Görünüşcə adi field kimidir, amma əslində hər şey nəzarət altındadır!
4. Niyə properties "Best Practice" sayılır
Çox vaxt biz obyektin daxili field-lərinə birbaşa giriş vermirik. Hətta indi yoxlama lazım deyil kimi görünsə də, məlumatları property ilə qorumaq vərdişi çox kömək edir, çünki qaydalar dəyişə bilər.
"Validasiya" nümunəsi təyin etmə zamanı:
public class Dog
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("İtin adı boş ola bilməz!");
}
_name = value;
}
}
}
İndi belə bir şey:
dog.Name = ""; // İstisna atacaq!
… obyektimizi absurd dəyərlərdən qoruyur.
5. Properties: yalnız oxumaq, yalnız yazmaq və adi
Bəzən yalnız dəyəri oxumağa icazə vermək lazımdır (məsələn, itin doğum ili var, onu dəyişmək olmaz), ya da əksinə — yalnız yazmaq (nadir hallarda, amma bəlkə nəsə sirli etmək istədin).
- Yalnız oxumaq: yalnız get yazırıq, set silirik.
- Yalnız yazmaq: yalnız set yazırıq, get silirik.
Nümunələr:
public class Dog
{
private int _birthYear = 2018;
// Yalnız oxumaq
public int BirthYear
{
get { return _birthYear; }
}
// Yalnız yazmaq (çox nadir hallarda rast gəlinir)
public string Secret
{
set { /* value ilə nəsə edirik */ }
}
}
6. Properties və field-lər
| Field | Property | |
|---|---|---|
| Sintaksis | |
|
| Giriş | Birbaşa | get/set vasitəsilə |
| Validasiya | Yoxdur | set/get-ə əlavə etmək olar |
| Genişlənmə | Yoxdur | İstənilən vaxt dəyişmək olar |
| IDE-inteqrasiya | Field kimi görünür | Property kimi görünür (framework-lər üçün vacibdir) |
İllustrasiya: Property-nin işi
sequenceDiagram
participant User as Obyekt istifadəçisi
participant Dog as Dog obyekti
participant Field as Private field _name
User->>Dog: dog.Name = "Rıjık"
Dog->>Dog: set Name("Rıjık")
Dog->>Field: _name = "Rıjık"
User->>Dog: print(dog.Name)
Dog->>Dog: get Name()
Dog->>Field: _name oxuyur
Dog->>User: "Rıjık" qaytarır
7. Tipik səhvlər və nüanslar
Gəlin baxaq, burada hansı tələlər ola bilər.
Tez-tez rast gəlinən səhv — field və property-ni qarışdırmaq, təsadüfən private məlumatları çölə açmaq:
public string name; // Bu field-dir! Hər yerdə görünür, təhlükəlidir!
Daha yaxşı variant:
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
Statik properties də olur, ümumi dəyərləri bütün obyektlər üçün saxlamaq üçün. Amma onlardan ehtiyatla istifadə et.
Maraqlıdır: əgər property-də yalnız get varsa və heç bir konstruktor yoxdursa, onu ümumiyyətlə dəyişmək mümkün deyil — bu immutable property adlanır və müasir dizayn yanaşmalarında aktiv istifadə olunur (bunu record və dəyişməz məlumatlar barədə dərslərdə ətraflı danışacağıq).
GO TO FULL VERSION