CodeGym /Kurslar /C# SELF /Kolleksiyalar: OrderedDictionary və ReadOnlySet

Kolleksiyalar: OrderedDictionary və ReadOnlySet

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

1. OrderedDictionary kolleksiyası

.NET-də həmişə zəngin standart kitabxana qiymətləndirilib, amma proqramçı həyatında kompromisli situasiyalar olurdu: həm dictionary istəyirsən ki, əlavə olunma sırasını yadda saxlasın, həm də dəyişməz unikal dəyərlər toplusu lazım olur. .NET 9-dan əvvəl üçüncü tərəf kitabxanalardan istifadə etməli idin ya da özün "velosiped" ixtira edirdin (bəziləri hətta GitHub-u açıb OrderedDictionary-ni oradan kopyalayırdı — şşş, heç kimə demərik).

.NET 9 çıxandan sonra yeni universal kolleksiyalar gəldi — artıq "kostil"lərə ehtiyac yoxdur! Gəlin ən faydalı ikisini detallı baxaq: OrderedDictionary<TKey, TValue> və ReadOnlySet<T>.

1. OrderedDictionary nədir?

OrderedDictionary — dictionary ilə list-in hibrididir. O, "açar-dəyər" cütlərini saxlayır, adi Dictionary<TKey, TValue> kimi, amma elementlərin sırası əlavə olunma sırasına tam uyğun olur. Bu xüsusilə vacibdir, əgər elementləri istifadəçi necə daxil edibsə, elə o cür sırayla keçmək lazımdırsa və ya sıranın biznes məntiqinə təsiri varsa: hesabat çapı, məlumatların serializasiyası, konfiqurasiya generasiyası və s.

Analoji

Adi dictionary — bu, bir sürü gözü olan şkaf kimidir, ora tez bir şey atıb çıxara bilərsən, sıranı düşünmədən. OrderedDictionary isə səliqəli, siyahı kimi şkafdır: hər şey ardıcıllıqla düzülüb və sən həmişə bilirsən nəyi əvvəl, nəyi sonra qoymusan.

2. Dictionary ilə əsas fərq

  • Dictionary: elementlərin sırası zəmanət verilmir (hətta sənə elə gəlirsə ki, həmişə eyni alınır — inanma, bu illüziyadır!).
  • OrderedDictionary: elementlər məhz əlavə olunduğu sırada saxlanılır.

3. Sintaksis və əsas metodlar

Budur, əsas istifadə nümunəsi:


using System.Collections.Generic;

var od = new OrderedDictionary<string, int>();
od.Add("Ivan", 5);
od.Add("Svetlana", 8);
od.Add("Alex", 3);

// Əlavə olunma sırasına görə dövr:
foreach (var pair in od)
{
    Console.WriteLine($"{pair.Key}: {pair.Value}");
}

Nəticə:

Ivan: 5
Svetlana: 8
Alex: 3

Əgər eyni nümunəni adi dictionary ilə yoxlasan, sıra çox vaxt fərqli olacaq. Amma OrderedDictionary ilə — həmişə əlavə etdiyin kimi olacaq.

OrderedDictionary adi dictionary-də olan interfeysləri dəstəkləyir:

  • IDictionary<TKey, TValue>
  • IReadOnlyDictionary<TKey, TValue>
  • IEnumerable<KeyValuePair<TKey, TValue>>

4. İndeks və açar üzrə çıxış

Xüsusiyyət: OrderedDictionary-də həm açar, həm də indeks üzrə çıxış var!


// Ad (açar) ilə:
int svetlanaScore = od["Svetlana"]; // 8

// İndeks ilə:
var firstEntry = od.ElementAt(0); // KeyValuePair<string, int>("Ivan", 5)

5. Yeniləmə və silmə

Əgər mövcud açarla yeni element əlavə etsən, istisna atılır. Dəyəri dəyişmək istəyirsənsə — indeksator istifadə et:

od["Ivan"] = 10; // Mövcudu dəyişir, sıra dəyişmir

Silmək həm açar, həm də indeks ilə mümkündür:


od.Remove("Svetlana");
od.RemoveAt(0);      // "Ivan"-ı silir

6. Strukturun vizuallaşdırılması


flowchart LR
    A("0: Ivan - 5")
    B("1: Svetlana - 8")
    C("2: Alex - 3")
    A --> B --> C
Hər düyün — açar-dəyər cütüdür, oxlar isə əlavə olunma sırasını göstərir.

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

Çox proqramçı Dictionary<TKey, TValue> istifadə edib sıraya ümid edir — amma bu, tələdir! Bəzən bir verilənlərdə sıra saxlanılır, amma başqa vaxt dəyişir (xüsusilə .NET dəyişəndə və ya başqa platformada).

OrderedDictionary-də sıra saxlandığı üçün bəzi əməliyyatlar (araya əlavə, ortadan silmə) bir az yavaşdır, amma əksər hallarda üstünlükləri daha çoxdur.

Əgər tez-tez indekslə axtarış lazımdırsa — bu, OrderedDictionary üçündür, amma yalnız açarla sürətli axtarış və sıra önəmsizdirsə — adi dictionary istifadə et.

8. Tətbiq üçün praktik nümunə

Tutaq ki, işçi və şöbələrin uçotu üçün tətbiqdə indi hesabat lazımdır, harada işçilər əlavə olunma sırasına görə çıxarılır:


var employeeScores = new OrderedDictionary<string, int>();
employeeScores.Add("Petr", 100);
employeeScores.Add("Anna", 150);
employeeScores.Add("Viktoriya", 80);

// Hesabat həmişə düzgün sırada:
foreach (var pair in employeeScores)
{
    Console.WriteLine($"{pair.Key}: {pair.Value} ballar");
}

2. ReadOnlySet<T> kolleksiyası

1. ReadOnlySet nədir?

ReadOnlySet<T> — dəyişməz (immutable) unikal dəyərlər toplusudur. Əvvəllər "yalnız oxumaq üçün set" yaratmaq üçün .ToHashSet() ilə kopya qaytarırdın və ya öz wrapper yazırdın. İndi isə elə bir kolleksiya var ki, yaradıldıqdan sonra ora nə əlavə, nə də silmək olar. Bu, kodun təhlükəsizliyini artırır və kənardan təsadüfi dəyişikliklərin qarşısını alır.

Analoji

Bu, elə bir dəftərdir ki, unikal adları yazmısan və... səhifələri laminat etmisən. Artıq heç kim ora nə əlavə, nə də silə bilməz.

2. ReadOnlySet yaratmaq

Dəyişməz set yaratmağın ən asan yolu extension metoddan istifadə etməkdir:


var colors = new[] { "Qırmızı", "Yaşıl", "Mavi", "Yaşıl" };
var readOnlyColors = colors.ToReadOnlySet();

// Burada yalnız unikal dəyərlər var və dəyişmək olmur:
foreach (var color in readOnlyColors)
    Console.WriteLine(color);

Nəticə:

Qırmızı
Yaşıl
Mavi

Birbaşa konstruktor da istifadə edə bilərsən (əgər lazımdırsa):


var set = new ReadOnlySet<int>(new[] {1, 2, 2, 3, 5, 1}); // Yenə də 1,2,3,5 olacaq

ReadOnlySet Microsoft Docs-da

3. Əsas xüsusiyyətlər və metodlar

  • Yalnız oxumaq (immutable)
  • Count — elementlərin sayı
  • Contains(item) — elementin olub-olmadığını yoxlayır
  • LINQ sorğularını dəstəkləyir (IEnumerable<T>)
  • Sürətli axtarış, amma əlavə, silmə, təmizləmə yoxdur

Nümunə:


if (readOnlyColors.Contains("Qırmızı"))
    Console.WriteLine("Qırmızı siyahıda var!");

Belə etmək olmaz:


// Kompilyasiya xətası!
readOnlyColors.Add("Sarı");

4. Harada işə yarayır?

Çox vaxt sənə məlumatı set kimi vermək lazımdır, amma istəmirsən ki, kimsə onu təsadüfən (ya da qəsdən) dəyişsin. Məsələn:

  • İstifadəçi rollarının siyahısını qaytarmaq
  • Fayl uzantılarının siyahısı
  • Dəyişmək olmaz konfiqurasiya parametrlərinin siyahısı

Tətbiqimizdə nümunə: tutaq ki, icazə verilən şöbələrin siyahısı var:


public static ReadOnlySet<string> Departments { get; } =
    new[] { "Kadrlar", "İnkişaf", "Mühasibatlıq" }.ToReadOnlySet();

Artıq heç kim şöbə siyahısını kənardan dəyişə bilməz.

5. Vizuallaşdırma: adi HashSet-dən fərqi


graph LR
    A[HashSet] -- Add/Remove/Contains --> B((Elements))
    C[ReadOnlySet] -- Only Contains --> D((Elements))
HashSet dəyişmək olar, ReadOnlySet — heç vaxt!

3. OrderedDictionary vs. ReadOnlySet: fərqlər cədvəli

Kolleksiya Cüt saxlayır? Sıra zəmanəti Dəyişmək olar Açarla axtarış İndekslə axtarış Ssenarilər
OrderedDictionary Bəli, "açar-dəyər" Bəli Bəli Bəli Bəli Xəritələr, ayarlar, hesabatlar
ReadOnlySet Xeyr, yalnız dəyərlər Xeyr Xeyr Bəli Xeyr Təhlükəsiz setlər, konstantlar
HashSet Xeyr, yalnız dəyərlər Xeyr Bəli Bəli Xeyr Dəyişmək lazım olan setlər
Dictionary Bəli, "açar-dəyər" Xeyr Bəli Bəli Xeyr Sıra önəmsiz xəritələr
2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
İndeksə görə giriş və OrderedDictionary-də elementin silinməsi
İndeksə görə giriş və OrderedDictionary-də elementin silinməsi
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION