Yükleniyor...

C# Generic Yapıları (List<T>, Dictionary<TKey,TValue>)

C# generic yapılarını öğrenin. List<T> ve Dictionary<TKey,TValue> ile tip güvenliği, yeniden kullanılabilirlik ve pratik örnekler.

C# dilinde generics, tür güvenliğini ve esnekliği artırmak için kullanılır. Generic sınıflar ve koleksiyonlar, çalışma zamanında tür dönüşümünü ve gereksiz boxing/unboxing işlemlerini ortadan kaldırarak performansı artırır ve hata riskini azaltır. Generics’in kullanılmaya başlanmasından önce, ArrayList gibi koleksiyonlar elemanları object türünde saklıyordu. int gibi bir değer tipi ArrayList içine eklendiğinde boxing işlemiyle object’e dönüştürülür, geri alınırken ise unboxing yapılırdı. Bu süreç ek bellek tahsisine ve performans kaybına neden olurdu. List<T> ve Dictionary<TKey,TValue> gibi generic koleksiyonlar sayesinde elemanlar gerçek türleriyle saklanır. Böylece bu maliyetler ortadan kalkar ve kod hem daha güvenli hem de daha hızlı hale gelir.


List<T>

List<T>, belirli bir türde elemanları dinamik olarak saklayan generic bir koleksiyondur. T burada listenin hangi türden elemanlar tutacağını belirtir.


using System;
using System.Collections.Generic;

var sayilar = new List<int>();
sayilar.Add(10);
sayilar.Add(20);
sayilar.Add(30);

foreach (int s in sayilar)
    Console.WriteLine(s);

// Çıktı:
// 10
// 20
// 30

Not: List<T> sabit boyutlu dizilerden farklı olarak büyüyüp küçülebilir.


Dictionary<TKey,TValue>

Dictionary, generic bir anahtar–değer koleksiyonudur. TKey anahtar türünü, TValue ise değer türünü belirtir.


using System;
using System.Collections.Generic;

var ogrenciler = new Dictionary<int, string>();
ogrenciler[101] = "Ali";
ogrenciler[102] = "Ayşe";
ogrenciler[103] = "Mehmet";

foreach (var kv in ogrenciler)
    Console.WriteLine($"{kv.Key} → {kv.Value}");

// Çıktı:
// 101 → Ali
// 102 → Ayşe
// 103 → Mehmet

Not: Dictionary’de her Key benzersizdir. Aynı anahtar tekrar eklenmek istenirse hata verir.


Kendi Generic Sınıflarınızı Yazmak

Sadece hazır koleksiyonlar değil, kendi generic tiplerinizi de tanımlayabilirsiniz. Bu sayede tekrar kullanılabilir, tip güvenli yapılar elde edilir.


public class Kutu<T>
{
    public T Deger { get; set; }

    public void Yazdir()
    {
        Console.WriteLine($"Kutu içeriği: {Deger}");
    }
}

class Program
{
    static void Main()
    {
        var intKutu = new Kutu<int> { Deger = 42 };
        intKutu.Yazdir();

        var stringKutu = new Kutu<string> { Deger = "Merhaba" };
        stringKutu.Yazdir();
    }
}

// Çıktı:
// Kutu içeriği: 42
// Kutu içeriği: Merhaba

Generic Kısıtlamaları (Constraints)

Generic tiplerde kısıtlamalar (where anahtar kelimesiyle) kullanılarak, parametre olarak verilen türlerin belirli özelliklere sahip olması zorunlu kılınabilir.


public class Depo<T> where T : class
{
    private readonly List<T> _items = new();

    public void Ekle(T item) => _items.Add(item);

    public void Listele()
    {
        foreach (var i in _items)
            Console.WriteLine(i);
    }
}

class Program
{
    static void Main()
    {
        var depo = new Depo<string>();
        depo.Ekle("Kalem");
        depo.Ekle("Defter");
        depo.Listele();
    }
}

// Çıktı:
// Kalem
// Defter

Örnek Uygulama: Ürün Yönetimi

Aşağıdaki örnekte ürün bilgileri List<Product> içinde saklanmakta, ürün ID–isim eşleşmeleri ise Dictionary<int,string> ile tutulmaktadır.


public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
}

class Program
{
    static void Main()
    {
        var urunler = new List<Product>
        {
            new Product { Id = 1, Name = "Bilgisayar" },
            new Product { Id = 2, Name = "Telefon" }
        };

        var urunSozluk = new Dictionary<int, string>();
        foreach (var u in urunler)
            urunSozluk[u.Id] = u.Name;

        Console.WriteLine("Ürünler:");
        foreach (var kv in urunSozluk)
            Console.WriteLine($"{kv.Key} - {kv.Value}");
    }
}

// Çıktı:
// Ürünler:
// 1 - Bilgisayar
// 2 - Telefon

LINQ alternatifi: Listeyi ToDictionary kullanarak doğrudan bir sözlüğe dönüştürebilirsiniz.


var urunSozluk = urunler.ToDictionary(p => p.Id, p => p.Name);

Console.WriteLine("Ürünler:");
foreach (var kv in urunSozluk)
    Console.WriteLine($"{kv.Key} - {kv.Value}");

TL;DR

  • Generic yapılar, tip güvenliğini artırır ve tekrar kullanılabilirliği sağlar.
  • List<T>: Dinamik, tip güvenli liste.
  • Dictionary<TKey,TValue>: Benzersiz anahtarlarla hızlı arama.
  • Kendi generic sınıflarınızı yazabilir, kısıtlamalarla tip güvenliği sağlayabilirsiniz.
  • Generic yapılar performanslıdır, boxing/unboxing ihtiyacını azaltır.

İlişkili Makaleler

C# Diziler (Array)

C#’ta dizileri (array) öğrenin. Eleman ekleme, erişim, döngülerle gezinme ve temel array işlemleri örneklerle anlatılıyor.

C# Veri Türü Dönüşümleri

C#’ta veri türü dönüşümlerini öğrenin. Implicit ve explicit casting, Parse, TryParse ve Convert yöntemleri örneklerle açıklanıyor.