CodeGym /Kurslar /C# SELF /Dəyişməzlik və with-i...

Dəyişməzlik və with-ifadələri

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

1. Dəyişməzlik nədir?

Gəlin analoji ilə başlayaq: təsəvvür et ki, sən hər gün satış hesabatı hazırlayan bir mühasibsən. Həqiqi peşəkar kimi, keçən həftənin hesabatını dəyişmirsən, sadəcə yenisini yaradırsan — köhnənin əsasında, amma yenilənmiş məlumatlarla. Proqramlaşdırmada dəyişməz obyektlər də eynidir: belə obyekt yaradıldıqdan sonra dəyişmir, istənilən "dəyişiklik" isə yeni bir kopyanın yaradılması deməkdir.

Dəyişməzlik (immutability) — obyektin ilkinizasiya olunduqdan sonra dəyişməməsi xüsusiyyətidir. Onun bütün xüsusiyyətləri "dondurulur": başqa dəyər istəyirsənsə — yeni obyekt yarat.

Bunun nə faydası var?

  • Təhlükəsizliyi təmin edir: əgər obyektini heç kim təsadüfən dəyişə bilmirsə, məlumatların birdən-birə pozulmaz. Bu, çox vaxt multithread proqramlarda olur, bir neçə thread eyni anda nəsə dəyişməyə çalışanda.
  • Debug-u asanlaşdırır: obyekt dəyişmirsə, onun yaradılmasından sonra nə baş verdiyini dəqiq bilirsən.
  • Məlumat ötürmək üçün rahatdır, xüsusilə paylanmış sistemlərdə, harada ki, kopyalar fərqli ola bilər.
  • "Vəziyyət snapshot-ları" (snapshots) yaratmağa imkan verir — dəyişikliklərin tarixi aydın olur.

2. record tiplərində dəyişməzlik

Adi class elan edəndə, xüsusiyyətləri default olaraq dəyişəndir (mutable). Nümunə:

public class UserProfile
{
    public string Name { get; set; }
    public int Age { get; set; }
}

var user = new UserProfile { Name = "İvan", Age = 25 };
user.Age = 26; // Hər şey ok — adi class: yaşı "uçan" dəyişirik

record üçün isə default vəziyyət fərqlidir: onlar dəyişməz məlumat saxlamaq üçündür.


public record UserProfile(string Name, int Age);

// Obyekt yaradırıq:
var user = new UserProfile("İvan", 25);

// Yaşı dəyişməyə çalışırıq:
user.Age = 26; // Kompilyasiya xətası: xüsusiyyət yalnız oxumaq üçündür!
record — xüsusiyyətlər yalnız oxumaq üçün (init-only)

Pozisional record xüsusiyyətləri yalnız oxumaq üçün (init-only) elan olunur. Onları yaradandan sonra dəyişə bilməzsən, amma with-ifadəsi ilə dəyişilmiş xüsusiyyətlərlə yeni kopya yarada bilərsən.

Dəyişən class-lar vs dəyişməz record-lar

Class Record-pozisional
Default xüsusiyyətlər
get; set;
Dəyişməz
get; init;
Necə dəyişmək olar
Xüsusiyyətə müraciət
Yalnız yeni kopya yaratmaqla
Obyektlərin müqayisəsi
Referansla (ReferenceEquals)
Dəyərlə (Equals)
Məlumat ötürmək üçün rahatdır
Həmişə deyil
Bəli

3. with-ifadələri

Yəqin düşündün — "record superdi, bəs indi necə yaşayaq, əgər onları dəyişmək olmursa?" Bax burada with-ifadələrinin magiyası gəlir!

with — xüsusi sintaksisdir, hansı ki, yeni kopya record yaradır, sadəcə lazım olan xüsusiyyətləri dəyişir.
Yəni: "Bu obyekti götür, kopyasını yarat, amma burda bir neçə xüsusiyyəti dəyiş."

Ən sadə nümunə


var user1 = new UserProfile("Anna", 30);
// ... amma həyat yerində durmur, Anna böyüdü
var user2 = user1 with { Age = 31 };
// user1 eyni qaldı, user2 — kopya, amma bir yaş böyük

Console.WriteLine(user1); // UserProfile { Name = Anna, Age = 30 }
Console.WriteLine(user2); // UserProfile { Name = Anna, Age = 31 }

Qapağın altında

Bu mutant-klon deyil, yeni obyektdir, hansı ki, xüsusi avtomatik yaradılan Clone() metodu ilə yaradılır, kopya yaradır və yeni dəyərləri qoyur.

Əgər with-ifadələri həyatda olsaydı, səhərlər "köhnə yorğun bədəndə" yox, özünün kopyasında, yaxşı əhval və daha böyük əzələlərlə oyanardın (amma yalnız record olsaydın).

4. Bir az iç-içəlik və kopyalama haqqında

Əgər record başqa record saxlayırsa — hər şey qaydasındadır:

public record Address(string City, string Street);
public record Student(string Name, int Age, string Email, Address Home);

var a1 = new Address("Moskva", "Tverskaya");
var s1 = new Student("Lena", 21, "lena@mail.ru", a1);

var s2 = s1 with { Home = a1 with { Street = "Arbat" } };

Burada hər şey həqiqətən dəyişməz işləyəcək, çünki içindəki Address də record-dur.

5. Son nüanslar

Pozisional record = qısa sintaksis

Record-u “qısa” formada (pozisional sintaksis) elan etmək olar. Onda bütün xüsusiyyətlər avtomatik olaraq init-only olur.

public record Course(string Name, int Credits);

var c1 = new Course("C#", 5);
var c2 = c1 with { Credits = 6 };

Yalnız oxumaq üçün xüsusiyyətlərə (init-only) bənzərlik

Record-da xüsusiyyətləri belə də açıq elan etmək olar:

public record Student
{
    public string Name { get; init; }
    public int Age { get; init; }
}

Belə xüsusiyyətləri də yalnız ilkinizasiya zamanı (və ya with ilə) dəyişmək olar.

6. Praktika: demo-tətbiq

Gəlin öz tədris "Online-məktəb"imizi yazaq. Tutaq ki, artıq tələbə üçün record-umuz var:

public record Student(string Name, int Age, string Email);

Klassika: kimsə email-də səhv edib, amma tələbə artıq hesab yaradıb. "Email-i yeniləmək" necə olsun? Əlbəttə, with ilə!


var student = new Student("Ekaterina", 19, "kate@school.com");
var updatedStudent = student with { Email = "ekaterina@school.com" };

// Obyektləri yoxlayaq:
Console.WriteLine(student);       // Student { Name = Ekaterina, Age = 19, Email = kate@school.com }
Console.WriteLine(updatedStudent); // Student { Name = Ekaterina, Age = 19, Email = ekaterina@school.com }

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

İndi bir az ağrıdan danışaq — tələbələrin dəyişməz record-larla oynayanda ən çox səhv etdiyi yerlər.

  • Birincisi, çoxları düşünür ki, with orijinal obyekti dəyişir. Əslində, orijinal obyekt eyni qalır, yeni isə dəyişilmiş sahələrlə yaradılır. Bəzən buna görə tələyə düşüb yeni dəyərləri itirirlər.
  • İkincisi, yadında saxla: əgər record-un içində dəyişən obyektlər varsa (məsələn, massiv və ya List), with-ifadəsi dərin kopyalama etmir! Kolleksiyan hər iki kopya üçün eyni olacaq.

public record Student(string Name, int Age, List<string> Subjects);

var s1 = new Student("Oleg", 22, new List<string> { "Math", "Physics" });
var s2 = s1 with { };

s1.Subjects.Add("C#"); // Bax, indi s2.Subjects də "C#" daxildir

Bax buna görə truly immutable state üçün yalnız sadə tiplər və ya özü dəyişməz olan kolleksiyalardan (ImmutableList<T> və s. System.Collections.Immutabledən) istifadə etmək yaxşıdır.

Əgər həqiqi dəyişməzlik istəyirsənsə, bu kolleksiyalardan istifadə et və ya manual dərin kopyalama et.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION