1. Tuple-ların adlandırılması: deconstruction üçün kontekst
Əvvəlki dərsdə artıq tuple-ların adlandırılmış elementləri ilə tanış olmuşduq, bu da koda çox daha oxunaqlı olmağa imkan verir, dəyərlərə adsız Item1, Item2 ilə yox, məna verən adlarla (məsələn, person.Name) müraciət etməyə imkan verir. Tuple elementlərinə ad vermək xüsusilə vacibdir, əgər onlar metodlardan, parametrlərdən və ya property-lərdən qaytarılan dəyərlər kimi istifadə olunursa. Məhz adlandırma rahat deconstruction üçün əsas şərtdir, bunu bu dərsdə daha ətraflı öyrənəcəyik.
Xatırladaq ki, adları tuple yaradanda literal vasitəsilə, həmçinin metodun, property-nin və ya field-in qaytarılan dəyərinin signaturasında vermək olar.
Metod nümunəsi: Tuple-un qaytarılan dəyərində adlandırılmış elementlər
public static (int Age, string Name) GetPetInfo()
{
return (Age: 5, Name: "Barsik");
}
// İstifadə:
var info = GetPetInfo();
Console.WriteLine($"{info.Name} — {info.Age} yaş");
Field/property nümunəsi: Field/property-də adlandırılmış tuple elementləri
public (int Width, int Height) ImageSize = (1024, 768);
Yadda saxla: əgər adlar açıq şəkildə verilməyibsə, elementlər yenə də Item1, Item2 və s. ilə əlçatan olacaq. Bu, kodu daha az oxunaqlı edə bilər, xüsusilə tuple-u sonradan istifadə edəndə. Ona görə də, həmişə elementlərə məna verən adlar vermək tövsiyə olunur, əgər onların mənası kontekstdən aydın deyilsə.
2. Tuple-ların deconstruction-u
Deconstruction nədir?
Deconstruction — tuple-u ayrıca dəyişənlərə "parçalamaq" prosesidir ki, onlarla rahat işləyə biləsən. Yəni, (Age: 5, Name: "Barsik") tuple-dan iki dəyişən ala bilərsən: age və name.
Bənzətmə: Təsəvvür elə ki, tuple — adlanmış hüceyrələri olan bir qutudur. Deconstruction — qutunun içindəkiləri birbaşa stolun üstünə öz yerlərinə qoymaqdır.
Deconstruction-un sintaksisi
var pet = (Age: 5, Name: "Barsik");
var (age, name) = pet;
Console.WriteLine($"{name} — {age} yaş");
İndi iki dəyişənimiz var: age və name. Onlar tuple-dan dəyərləri aldılar. Soldakı adlar (age, name) tuple-dakı adlarla üst-üstə düşməyə bilər, bunlar sadəcə yeni lokal dəyişənlərdir.
Funksiyanın qaytardığı dəyərin deconstruction-u
Çox vaxt tuple-lar funksiyadan bir neçə dəyər qaytarmaq üçün istifadə olunur. Orada deconstruction xüsusilə rahatdır:
public static (double min, double max) GetMinMax(int[] data)
{
int min = data.Min();
int max = data.Max();
return (min, max);
}
var numbers = new[] { 1, 2, 3, 4, 5 };
var (minValue, maxValue) = GetMinMax(numbers);
Console.WriteLine($"Minimum: {minValue}, maksimum: {maxValue}");
Diqqət elə, deconstruction-da dəyişənləri istədiyin kimi adlandıra bilərsən, əsas odur ki, kontekstdə rahat olsun.
var ilə deconstruction
var (a, b) = (10, 20); // int a = 10, b = 20
Deconstruction və discard _
Bəzən tuple-un bütün elementləri lazım olmur. Onları _ (discard) ilə görməməzliyə vurmaq olar. Discard (_) tuple-da sadəcə deməkdir ki, "burada daha bir element var, amma mənə lazım deyil, onun üçün dəyişən yaratma".
Yəni, tuple-u deconstruction edirsən, amma lazım olmayan yerdə "boşluq" qoyursan. Qısa, rahat və kompromisssiz!
var pet = (Age: 5, Name: "Barsik", IsHappy: true);
var (age, _, isHappy) = pet; // yalnız age və isHappy, name-i görməməzliyə vurduq
Maraqlı fakt: discard tez-tez istifadə olunur ki, lazım olmayan dəyişənlər namespace-i çirkləndirməsin.
foreach dövründə deconstruction
C#-da tuple-lardan ibarət massivi birbaşa foreach konstruksiyasında deconstruction ilə iterasiya etmək olar:
var pets = new (string Name, int Age)[]
{
("Barsik", 5),
("Musya", 3),
("Jonni", 7)
};
foreach (var (name, age) in pets)
{
Console.WriteLine($"{name} — {age} yaş");
}
3. Element adları və tipizasiya necə işləyir
Adlandırılmış elementlərin davranışı
Tuple-un element adları — "syntactic sugar"-dır, yəni insan üçün rahatlıqdır. Kompilyasiya zamanı adlar daxili Item1, Item2 və s. sahələrə çevrilir, amma IDE və kompilyator adları saxlayır ki, sən onlardan istifadə edə biləsən.
Tip uyğunluğuna və cast-ə təsiri
Eyni sayda və tipdə elementləri olan iki tuple, adları fərqli olsa da, kompilyator üçün eyni tip sayılır. Element adları tipin tərifinə daxil deyil:
var t1 = (X: 42, Y: 13);
var t2 = (A: 42, B: 13);
t1 = t2; // OK
Console.WriteLine(t1.X); // 42
Amma ifadələrlə və IntelliSense podskazkaları ilə işləyəndə, soldakı (hansı ki, təyin edirik) adlar istifadə olunacaq, sağdakılar yox.
Adların açıq və gizli verilməsi
Bunu artıq öyrənmişik, amma bir daha deyək ki, tuple-ları qismən adlandırılmış elementlərlə yarada bilərsən, ya da ümumiyyətlə ad verməyə bilərsən — o zaman sadəcə Item1 və s. olacaq.
var point = (X: 10, 20); // X və Item2
Console.WriteLine(point.X); // 10
Console.WriteLine(point.Item2); // 20
Məsləhət: əgər tuple bir-iki elementdən çoxdursa və ya dəyərin mənası kontekstdən aydın deyilsə, həmişə elementləri adlandır.
4. Adlarla və deconstruction ilə işləyərkən tipik səhvlər və xüsusiyyətlər
Səhv №1: fərqli tuple-ları təyin edəndə adların "köçməsi"
Əgər əvvəlcə bir tuple-u bir adlarla elan etmisənsə, sonra ona başqa tuple (adlarla və ya adsız) təyin etmisənsə, IntelliSense yenə də ilkin adları göstərəcək. Məsələn:
var original = (X: 1, Y: 2);
var alias = original; // alias.X == 1, alias.Y == 2
original = (10, 20); // adsız tuple
Console.WriteLine(alias.X); // hələ də işləyir, amma alias köhnə adları saxlayır
Səhv №2: element adlarının təkrarı.
İki elementə eyni ad vermək olmaz — kompilyator "Duplicate tuple element name" mesajı verəcək:
var badTuple = (A: 1, A: 2); // Səhv CS8122: Duplicate tuple element name 'A'
Səhv №3: element sayı üzrə yanlış deconstruction.
Deconstruction zamanı dəyişənlərin sayı tuple-un ölçüsü ilə tam uyğun olmalıdır. Uyğunsuzluq səhvə səbəb olacaq:
var pet = (Age: 5, Name: "Barsik");
var (age, name, mood) = pet; // Səhv CS8124: Tuple must contain exactly 3 elements
Səhv №4: discard _ düzgün istifadə olunmur
Elementləri _ ilə görməməzliyə vurmaq hər yer üçün ayrıca işləyir və "boşluqları" birləşdirmir. Məsələn, eyni anda iki elementi bir _ ilə atlamağa çalışsan, səhv alacaqsan:
var data = (1, 2, 3);
var (_, x, _) = data; // Düzgün: birinci və üçüncü element atlanıb
var (_, _) = data; // Səhv CS8124: Tuple must contain exactly 2 elements
GO TO FULL VERSION