Unity Eğitim
Dersler
Forum Sınav Merkezi Premium 💎
C# Dersleri

C# LINQ ile Veri İşleme: Filtreleme, Sıralama ve Projeksiyon

Paylaşan: Unity Eğitim 25 October 2025 9 dakika okuma 68 görüntülenme

Unity ve C# ile oyun geliştirirken sıkça karşılaşılan durumlardan biri, büyük veri koleksiyonlarını (listeler, diziler vb.) işlemek, belirli kriterlere göre filtrelemek, düzenlemek veya farklı formatlara dönüştürmektir. Bu tür işlemler için C# dilinin ayrılmaz bir parçası olan LINQ (Language Integrated Query) harika bir çözüm sunar. Bu makalede, C# LINQ kullanımı ile veri koleksiyonlarınızı nasıl filtreleyeceğinizi, sıralayacağınızı ve projeksiyon uygulayarak dönüştüreceğinizi detaylıca inceleyeceğiz.

Giriş: C# LINQ Nedir?

LINQ, C# programlama diline entegre edilmiş bir sorgulama dilidir. SQL'e benzer bir sözdizimi kullanarak, farklı veri kaynaklarındaki (bellek içi nesneler, veritabanları, XML belgeleri vb.) verileri tutarlı bir şekilde sorgulamanızı sağlar. Özellikle koleksiyonlar üzerinde çalışırken, geleneksel döngüler ve koşullu ifadeler yerine daha okunabilir, daha kısa ve daha güçlü kod yazmanıza olanak tanır.

LINQ'in Temel Faydaları

  • Okunabilirlik: Sorgular, verinin ne yaptığını açıkça ifade eder.
  • Az Kod: Karmaşık işlemleri çok daha az kod satırıyla gerçekleştirmenizi sağlar.
  • Güvenlik: Derleme zamanı tipi kontrolü sayesinde hataları erken yakalamanıza yardımcı olur.
  • Esneklik: Farklı veri kaynakları üzerinde aynı sözdizimi ile çalışabilir.

C# LINQ Kullanımı: Temeller

LINQ sorgularını yazmanın iki ana yolu vardır: Sorgu Sözdizimi (Query Syntax) ve Metot Sözdizimi (Method Syntax). Unity projelerinde ve genel C# geliştirme pratiğinde Metot Sözdizimi daha yaygın olarak kullanılır, çünkü daha esnek olup lambda ifadeleriyle mükemmel bir uyum içindedir. Bu makalede Metot Sözdizimi'ne odaklanacağız.

Ertelemeli Yürütme (Deferred Execution) Kavramı

LINQ'in en önemli özelliklerinden biri ertelemeli yürütmedir. Bu, bir LINQ sorgusu tanımladığınızda, sorgunun hemen yürütülmediği anlamına gelir. Sorgu, ancak sonuçlara gerçekten ihtiyaç duyulduğunda (örneğin, bir foreach döngüsüyle erişildiğinde veya ToList(), ToArray() gibi metotlar çağrıldığında) çalıştırılır. Bu özellik, özellikle büyük veri kümeleriyle çalışırken performans optimizasyonu sağlar.

Filtreleme (Filtering) İşlemleri: Where() Metodu

Bir veri koleksiyonundan belirli koşulları sağlayan öğeleri seçmek için Where() metodunu kullanırız. Bu metot, bir koşul (lambda ifadesi olarak) alır ve bu koşulu sağlayan öğeleri içeren yeni bir IEnumerable döndürür.

Örnek: Oyuncu Listesini Filtreleme

using System;
using System.Collections.Generic;
using System.Linq;

public class Oyuncu
{
    public string Ad { get; set; }
    public int Seviye { get; set; }
    public bool AktifMi { get; set; }
}

public class LINQFiltrelemeOrnegi
{
    public static void Main()
    {
        List<Oyuncu> oyuncular = new List<Oyuncu>()
        {
            new Oyuncu { Ad = "Elara", Seviye = 15, AktifMi = true },
            new Oyuncu { Ad = "Kael", Seviye = 8, AktifMi = false },
            new Oyuncu { Ad = "Lyra", Seviye = 22, AktifMi = true },
            new Oyuncu { Ad = "Zorion", Seviye = 15, AktifMi = true },
            new Oyuncu { Ad = "Mira", Seviye = 5, AktifMi = false }
        };

        // Seviyesi 10'dan yüksek olan aktif oyuncuları filtrele
        var yuksekSeviyeliAktifOyuncular = oyuncular.Where(o => o.Seviye > 10 && o.AktifMi);

        Console.WriteLine("Yüksek Seviyeli Aktif Oyuncular:");
        foreach (var oyuncu in yuksekSeviyeliAktifOyuncular)
        {
            Console.WriteLine($"Ad: {oyuncu.Ad}, Seviye: {oyuncu.Seviye}");
        }

        // Adı 'M' ile başlayan oyuncuları filtrele
        var mIleBaslayanlar = oyuncular.Where(o => o.Ad.StartsWith("M"));

        Console.WriteLine("\nM ile Başlayan Oyuncular:");
        foreach (var oyuncu in mIleBaslayanlar)
        {
            Console.WriteLine($"Ad: {oyuncu.Ad}");
        }
    }
}

Sıralama (Ordering) İşlemleri: OrderBy(), ThenBy()

Veri koleksiyonundaki öğeleri belirli bir kritere göre sıralamak için OrderBy() ve OrderByDescending() metotlarını kullanırız. Birden fazla kritere göre sıralama yapmak için ise ThenBy() ve ThenByDescending() metotları devreye girer. Bu metotlar da C# LINQ kullanımı içinde temel sıralama ihtiyaçlarını karşılar.

Artan ve Azalan Sıralama

// Oyuncuları seviyeye göre artan sırada sırala
var seviyeyeGoreSirali = oyuncular.OrderBy(o => o.Seviye);

Console.WriteLine("\nSeviyeye Göre Artan Sıralama:");
foreach (var oyuncu in seviyeyeGoreSirali)
{
    Console.WriteLine($"Ad: {oyuncu.Ad}, Seviye: {oyuncu.Seviye}");
}

// Oyuncuları seviyeye göre azalan sırada sırala
var seviyeyeGoreAzalan = oyuncular.OrderByDescending(o => o.Seviye);

Console.WriteLine("\nSeviyeye Göre Azalan Sıralama:");
foreach (var oyuncu in seviyeyeGoreAzalan)
{
    Console.WriteLine($"Ad: {oyuncu.Ad}, Seviye: {oyuncu.Seviye}");
}

Çoklu Kriterle Sıralama

Önce seviyeye göre, ardından aynı seviyedeki oyuncuları isme göre sıralamak isteyebiliriz:

// Önce seviyeye göre artan, sonra ada göre artan sırala
var cokluKriterSirali = oyuncular
    .OrderBy(o => o.Seviye)
    .ThenBy(o => o.Ad);

Console.WriteLine("\nÇoklu Kriterle Sıralama (Seviye, sonra Ad):");
foreach (var oyuncu in cokluKriterSirali)
{
    Console.WriteLine($"Ad: {oyuncu.Ad}, Seviye: {oyuncu.Seviye}");
}

Projeksiyon (Projection) İşlemleri: Select() Metodu

Projeksiyon, bir koleksiyondaki her öğeyi yeni bir forma veya tipe dönüştürme işlemidir. Örneğin, bir oyuncu listesinden sadece oyuncuların isimlerini veya başka bir nesne türünü çıkarmak isteyebilirsiniz. Select() metodu bu iş için kullanılır.

Veriyi Dönüştürme

// Oyuncu listesinden sadece isimleri al
var oyuncuIsimleri = oyuncular.Select(o => o.Ad);

Console.WriteLine("\nOyuncu İsimleri:");
foreach (var isim in oyuncuIsimleri)
{
    Console.WriteLine(isim);
}

// Oyuncuların adını ve seviyesini içeren yeni, anonim bir tip oluştur
var oyuncuBilgileri = oyuncular.Select(o => new { o.Ad, o.Seviye });

Console.WriteLine("\nOyuncu Ad ve Seviye Bilgileri:");
foreach (var bilgi in oyuncuBilgileri)
{
    Console.WriteLine($"Ad: {bilgi.Ad}, Seviye: {bilgi.Seviye}");
}

Pratik İpuçları ve En İyi Uygulamalar

Zincirleme (Method Chaining)

LINQ metotları, IEnumerable döndürdüğü için zincirleme şeklinde kullanılabilir. Bu, birden fazla filtreleme, sıralama ve projeksiyon işlemini tek bir akıcı ifadeyle birleştirmenizi sağlar. Bu, C# LINQ kullanımı pratiğinde oldukça yaygın ve okunabilir bir yaklaşımdır.

// Seviyesi 10'dan yüksek ve aktif olan oyuncuların sadece adlarını al ve alfabetik sırala
var nihaiSonuc = oyuncular
    .Where(o => o.Seviye > 10 && o.AktifMi)
    .OrderBy(o => o.Ad)
    .Select(o => o.Ad);

Console.WriteLine("\nZincirleme ile Nihai Sonuç:");
foreach (var ad in nihaiSonuc)
{
    Console.WriteLine(ad);
}

ToList() veya ToArray() Ne Zaman Kullanılmalı?

Yukarıda bahsedilen ertelemeli yürütme nedeniyle, bir LINQ sorgusunun sonucunu bellekte somutlaştırmak istediğinizde ToList() veya ToArray() metotlarını kullanmalısınız. Bu, özellikle sorgu sonucunu birden fazla kez kullanacaksanız veya sonucu değiştirecekseniz önemlidir. Aksi takdirde, her erişimde sorgu yeniden çalışabilir, bu da performansı etkileyebilir.

// Sorguyu hemen yürüt ve sonucu bir listeye at
List<Oyuncu> filtrelenmisOyuncular = oyuncular
    .Where(o => o.Seviye > 10)
    .ToList();

// Artık 'filtrelenmisOyuncular' listesi bellekte somutlaşmıştır.

Okunabilirliği Artırma

Karmaşık LINQ sorgularını daha okunabilir hale getirmek için her metodu ayrı bir satıra yazabilir ve girintileme kullanabilirsiniz. Bu, özellikle uzun zincirleme ifadelerde kodun anlaşılmasını kolaylaştırır.

Yaygın Hatalar ve Çözümleri

Ertelemeli Yürütmeyi Yanlış Anlamak

En yaygın hatalardan biri, ertelemeli yürütmeyi göz ardı etmektir. Bir sorgu tanımladıktan sonra, orijinal koleksiyonu değiştirirseniz, sorgu çalıştırıldığında bu değişiklikler sonuçları etkileyecektir. Eğer bu istenmiyorsa, sorgu sonucunu ToList() veya ToArray() ile hemen somutlaştırın.

Null Referans Hatalarından Kaçınma

LINQ sorgularında null referanslarla çalışırken dikkatli olun. Örneğin, bir nesnenin özelliği null olabilecekse, Where() içinde kontrol etmeniz gerekebilir:

// Adı null olmayan oyuncuları filtrele
var adNullOlmayanlar = oyuncular.Where(o => o.Ad != null && o.Ad.Contains("a"));

Gereksiz Bellek Kullanımı

Büyük koleksiyonlarla çalışırken her adımda ToList() veya ToArray() çağırmak gereksiz bellek tahsisine yol açabilir. Sadece sorgu sonucunu gerçekten bir listeye veya diziye dönüştürmeniz gerektiğinde bu metotları kullanın. Aksi takdirde, IEnumerable olarak çalışmaya devam etmek daha verimlidir.

Performans ve Optimizasyon Notları

Büyük Koleksiyonlarda Dikkat

Çok büyük koleksiyonlar üzerinde karmaşık LINQ sorguları çalıştırmak performans sorunlarına yol açabilir. Özellikle Unity'nin ana döngüsü (Update()) içinde sıkça çalışan sorgularda dikkatli olun. Bu tür durumlarda, verileri önceden işlemek veya sorguyu daha küçük parçalara bölmek gibi stratejiler düşünebilirsiniz.

Sorguyu Erken Sonlandırma Metotları

Bazen sadece bir öğeye veya belirli bir özelliğe ihtiyacınız olabilir. Bu durumda, tüm koleksiyonu işlemek yerine sorguyu erken sonlandıran metotları kullanmak performansı artırır:

  • FirstOrDefault(): Koşulu sağlayan ilk öğeyi veya varsayılan değeri döndürür.
  • Any(): Koleksiyonda koşulu sağlayan herhangi bir öğe olup olmadığını kontrol eder.
  • Count(): Koşulu sağlayan öğelerin sayısını döndürür.
  • Single() / SingleOrDefault(): Koşulu sağlayan tek bir öğeyi bekler.
// Seviyesi 20'den yüksek ilk aktif oyuncuyu bul
var ilkYuksekSeviyeliAktif = oyuncular
    .FirstOrDefault(o => o.Seviye > 20 && o.AktifMi);

if (ilkYuksekSeviyeliAktif != null)
{
    Console.WriteLine($"\nBulunan ilk yüksek seviyeli aktif oyuncu: {ilkYuksekSeviyeliAktif.Ad}");
}

// Aktif oyuncu var mı?
bool aktifOyuncuVarMi = oyuncular.Any(o => o.AktifMi);
Console.WriteLine($"Aktif oyuncu var mı? {aktifOyuncuVarMi}");

Sonuç

LINQ, C# geliştiricilerinin veri manipülasyonu görevlerini daha zarif, okunabilir ve verimli bir şekilde yapmalarını sağlayan güçlü bir araçtır. Filtreleme, sıralama ve projeksiyon gibi temel işlemler, C# LINQ kullanımı ile çok daha kolay hale gelir. Ertelemeli yürütme, zincirleme metotlar ve performans ipuçlarını göz önünde bulundurarak, Unity projelerinizde ve genel C# uygulamalarınızda daha temiz ve optimize kod yazabilirsiniz. LINQ'i öğrenmek ve pratiğe dökmek, şüphesiz programlama yeteneklerinizi bir üst seviyeye taşıyacaktır.

🧠 Ders Sonu Değerlendirme Testi

Dersi tamamladıktan sonra bilgilerinizi test edin ve ekstra puanlar kazanın.

🔥 +50 XP Ödül
🔒

Sınava Katılmak İçin Giriş Yapın

Bu ders sonu testini çözebilmek, bilginizi test edip **+50 XP** kazanmak ve **Sınav Şampiyonu** rozetinin kilidini açmak için üye girişi yapmalısınız.

Yorumlar (0)

Yorum yazabilmek ve derslere katkıda bulunabilmek için giriş yapmalısınız.

İlk yorumu siz yapın!