Mənim bloqum

Encapsulation Nədir?

Encapulation bir obyekt içərisindəki dataların (Field-dəki dataların) çölə kontrollu şəkildə göndərilməsi və kontrollu şəkildə qəbul edilməsidir. Burada Property köməkliyi ilə datalar kapsulla alınaraq qorunur və daha təhlükəsiz şəkildə işlənir. Demək olar ki, bütün proses developer-in nəzarəti altında olub tələbə uyğun baş verir.


Propery Nədir?

"Class member" termini proqramlaşdırmada Class içərisində təyin olunan dəyişənlər, sabitlər(Const) və funksiyalardır. Bu member-lərdən biri də Property-dir. Property əslində metod-dur. Yəni proqramatik/alqoritmik kodlarımızı yazdığımız metod-dur. Lakin, metoddan fərqi: parametr almaması və içərisində get, set olmaqla 2 kod blokundan ibarət olmasıdır.

                        
                                                                                                                                                                                

public int X
{
   get
    {
       return 0;
    }
   set
    {
          //burada dəyər set olunur
    }
}
                                                     
                                                     
                                                     
                                                                             
                                                                            
image

Metod nədir ?

C# proqramlaşdırma dilində metod, müəyyən bir tapşırığı yerinə yetirən, gördüyü işə uyğun adlandırılmış bir kod blokudur. Metodlar, kodu hissələrə bölmək, təkrarı önləmək, modulları artırmaq və kodun oxunqlığını və davamlılığını artırmaq məqsədilə istifadə olunur. Daha geniş şəkildə mövzuya başqa məqalədə toxunacayıq.

                        
                                                                                                                                                                                
static void MyMethod() 
{
  Console.WriteLine("Metodu çap et!");
}

static void Main(string[] args)
{
  MyMethod();
  MyMethod();
  MyMethod();
}
                                                     
                                                     
                                                     
                                                                             
                                                                            

Property-nin Metod-dan fərqi

Propery-ə dəyər təyin etdikdə set bloku, dəyəri oxumaq istədiyimizdə isə get bloku işə düşür. Funksionallıq baxımdan property-nin metoddan fərqi yoxdur. Metod ilə nə ediriksə property də eyni cür istifadə olunur. Lakin property bir davranış olaraq obyekt üzərindən dəyərin oxunması, təyin olunması proseslərində spesifik olaraq istifadə olunan C#-a özəl bir strukturdur. Property birbaşa "Field" mövzusu ilə əlaqəlidir. Biz bəzən hansısas səbəbdən obyekt içərisində təyin etdiyimiz field-lərin çöldən əlçatan olmamasını istəyirik. Yəni field-lərdəki dəyərləri çölə kontrollu şəkildə, öz qoyduğumuz şərtlərlə ötürmək istəyirik. Bu tip kontrolu da bizə Property təmin edir.


Property-nin işləmə prinsipi

Aşağıdakı nümunədən də gördüyünüz kimi normal şəkildə get və set metodları təyin edərək `sample` obyekti üzərindən access-imizin olmadığı default-u private olan `_num` field-ə kontrollu şəkildə dəyər təyin etdik və onu əldə etdib ekrana yazdıq. Bu normal Java, PHP kimi proqramlaşdırma dillərində istifadə olunan metoddur. C#-da isə bu kimi spesifik hallar üçün Property anlayışı mövcuddur. Sadəcə, C# öz fərqini yaradır deyə bilərik. Bilməli olduğumuz digər məsələ isə Property-nin gördüyü işin heç də aşağıdakı prosesdən fərqlənməməsidir. Bəzi quruluşlar bunu arxa planda edir(prop) bəzisində isə açıq şəkildə(propfull). Aşağıdakı Full Property-ə nəzər yetirsəniz _num field-ə kontrollu şəkildə, tələbə uyğun məlumat əlavə olundu. Əldə edildiyi zaman da yenə tələbə uyğun müəyyən dəyişiklər olunaraq datanı çölə göndərdi. Amma bu dəfə daha struklturlu və spesifik halda. Datanı göndərən və ya qəbul edən arxa planda gedən proslərdən xəbərsizdir. Elə bilir ki, nə dəyər göndərirsə onu da təyin edirik, ancaq, arxa planda biz bunu özəlləşdirdiyimizdən full kontrol bizdə olur :) Düşünürəm ki, artıq aradakı fərqi və zərurəti ayırd etmiş oldunuz. Artıq, Property-nin bu funksiyasına "Encapsulation" (Kapsullama) deyə bilərik. Təbii ki, növbəti məqalələrdə Reflection mövzularına keçid edəndə görəcəyik ki, member-lərə sadəcə private access modifier təyin etməklə onun əlçatanlığını qısıtlamış, 100% təhlükəsiz etmiş olmuruq. Reflection-la istər private istər public member-lərin dəyərlərini əldə etmiş oluruq. Ancaq, bunun xaricində datalarımızı nisbətən qorunmuş hesab edə bilərik :) Property təmsil etdiyi field-lə eyni tipdə olmalıdır ki, ona uyğun dəyər gətirib-apara bilsin. Property özlüyündə bir metod olduğu üçün böyük hərflə başlaması adlandırma baxımdan önəm kəsb edir.

                        
                                                                                                                                                                                

public class Sample_Property
{
    int _num;

    public void Set(int num)
    {
        _num = num;
    }

    public int Get()
    {
        return _num;
    }
}


namespace Blogs.Blog_1
{
    public class Progam
    {
        public static void Main(string[] args)
        {
            Sample_Property sample = new();
            sample.Set(1);  //dəyər təyin etdikdə çağırılan metod

            Console.WriteLine(sample.Get()); //təyin etdiyimiz dəyəri əldə edəndə çağırılan metod
        }
    }
}
                                                     
                                                     
                                                     
                                                                             
                                                                            
image

Property-nin Növləri

- Full Property - Prop - Auto Property Initializers - Ref Readonly Returns - Computed Properties - Expression-Bodied Property - Init-Only Properities və Init Accessor


Full Property

Class içərisində propfull yazıb tab-a basdıqda bənzər (ola bilsin adlandırma fərqli olsun) bir struktur görəcəksiniz.Əgər aşağıda gördüyünüz nümunədəki kimi gələn və gedən data üzərində dəyişikliklər edəcəksinizsə onda bu property-dən istifadə edə bilərsiniz. Ən sadə Property şablonudur. Full property-dəm Set blokunu silsək, sadəcə readonly(oxunabilən) olacaq, yəni dəyər set edə bilmərik. Sadəcə, mövcud dəyəri oxuya bilərik. Əgər Get blokunu silsək onda da sadəcə writeonly(yazılabilən) olacaq yəni Get bloku işləməyəcək. Bu qısıtlamaıları private access modifier ilə də edə bilərik. Private field-lərin də altdan xətt və kiçiklə (_example) yazılmasına da diqqət etməyiniz üstünlükdür. Tələbə uyğun istifadə edə bilərsiniz.

                        
                                                                                                                                                                                

public class Sample_Property
{
    int _num;

    public int Num
    {
        get 
        {
            return _num - 2; //get blokundakı dəyər property tipində olmalıdır. Nə də olsa dəyəri bu property geri qaytarırır
        }
        set
        {
            _num = value + 5; //value - property çağırılanda təyin edilən, içəriyə göndərilən dəyəri təmsil edir
        }
    }

}

namespace Blogs.Blog_1
{
    public class Progam
    {
        public static void Main(string[] args)
        {
            Sample_Property sample = new();
            sample.Num = 9;  //dəyər təyin etdikdə çağırılan metod

            Console.WriteLine(sample.Num); //təyin etdiyimiz dəyəri əldə edəndə çağırılan metod --> Output : 12 
        }
    }
}
                                                     
                                                     
                                                     
                                                                             
                                                                            

Prop

Class içərisində prop + Tab -a basaraq şablonu yarada bilərsiniz. Gələn və gedən dataya hansısa şəkildə müdaxilə etməyəcəksinizsə onda bu property şablonundan istifadə edə bilərsiniz. Bu şablonda field təyin etmirik. Compiler özü arxa planda default field təyin edir. Get, Set blokları da bizim heç bir müdaxiləmiz olmadan arxa planda öz işlərini görür.

                        
                                                                                                                                                                                
public int MyProperty { get; set; }
                                                     
                                                     
                                                     
                                                                             
                                                                            

Auto Property Initializers

Prop şablonunda property readonly(Set bloku olmadan) ola bilir çünki, Compiler özü arxa planda type-na uyğun dəyər set edir. Amma writeonly(Get bloku olmadan) ola bilməz. Comiler səviyyəsində xəta verəcək. İstifadə edə bilməyəcəyin şeyi niyə təyin edəsən ki? "Auto Property Initializer" xüsusiyyətinə əsasən biz property-ni readonly(Set blokunu silməklə) təyin etsək belə təyin etdiyimiz anda defualt dəyərini bizim set etməyimizə şərait yaradır. Bunun məntiqi də onsuz biz dəyər təyin etməsək Compiler arxa planda ona tipinə uyğun default dəyər təyin edəcəkdi, ona görə o default dəyərin bizim seçimimiz olmasına icazə verir. Çox centlmendir :)

                        
                                                                                                                                                                                
public int Num { get;  } = 9; //sonradan çağırıb dəyər təyin edə bilmərik

 public int Num { get; set; } = 9; //istənilən property-ə bu şəkildə default dəyər təyin edə bilərik
                                                     
                                                     
                                                     
                                                                             
                                                                            

Ref Readonly Returns

Bu xüsusiyyət bir class içərisindəki field-i referansı ilə birgə qaytarmağımızı təmin edir. Normalda bir metoda dəyər ötürüldükdə qiymət kopyalanır və bu şəkildə proses yerinə yetirilir. Bununla belə, ref istifadə edildikdə, original dəyəri daşıyan referans ötürülür, bu, əlavə kopyalamanın qarşısını alır və performansı yaxşılaşdırır. Readonly isə sadəcə oxu əməliyyatlarının yerinə yetirilməsinə icazə verir. Bu, istinad edilən obyektin məzmununun dəyişdirilməsinin qarşısını almaq üçün təhlükəsizlik tədbiridir.

                        
                                                                                                                                                                                
public class Program
 {
     string _color = "Pink";
     public ref readonly string Color => ref _color;
 }
                                                     
                                                     
                                                     
                                                                             
                                                                            

Computed Properties

Computed Properties istifadəsi class-dan kənar istifadəçilərə fərdi hesablama və ya məntiq təqdim etmək məqsədi daşıyır.

                        
                                                                                                                                                                                
public class Rectangle
{
    public int Width { get; set; }
    public int Height { get; set; }
    public int Area
    {
        get { return Width * Height; }
    }
}
                                                     
                                                     
                                                     
                                                                             
                                                                            

Expression-Bodied Property

Bu şablondakı property Lambda expression istifadə etməyimizə imkan yaradır. Sadəcə readonly property-lərdə istifadə olunur. Sadə bir nümunə ilə nəzər yetirək. İlk dəyərlər təyin edilmə məntiqində bir az da Auto Property Initializer ilə yaxındır.

                        
                                                                                                                                                                                
public class Program
 {
     public bool Check => true;
 }
                                                     
                                                     
                                                     
                                                                             
                                                                            

Init-Only Properities və Init Accessor

Init-Only Properity obyektin ilk yaradılma anında dəyər təyin etməyimizə icazə verməsidir. Beləliklə runtime-da obyektlərin dəyərinin dəyişdirilməsinin qarşısı alınır. Məsələn, digər property-lərlə bənzərliyini müqayisə edəsi olsaq ilk yaradılan zaman default dəyər təyin edilməs xüsusiyyətinə görə Auto Property Initializer yadınıza düşmüş ola bilər ama onun obyekt yaradılan zaman dəyər təyin edilməsinə icazə vermədiyini yadımıza salaq. O, sadəcə property özü təyin olunduğu anda dəyər set etməyə icazə verirdi. Init-Only Properity isə obyektin təyin edilmə zamanında icazə verir daha sonra bir daha dəyişdirilməsinə icazə vermir. Readonly olaraq davam etməsini tələb edir

                        
                                                                                                                                                                                
public class Sample_Property
{
    public string Name { get; init; }
    public string Surname { get; init; }
}


namespace Blogs.Blog_1
{
    public class Progam
    {
        public static void Main(string[] args)
        {
            Sample_Property sample = new()
            {
                Name = "test",
                Surname = "test",
            };

            sample.Name = "test";//dəyər təyin etməyə çalışsaq icazə verilmədiyinə dair xəta alarıq

        }
    }
}