2026 – 2027 Eğitim Dönemi erken kayıt dönemi başladı. Birebir eğitim programlarımız 21 Eylül 2026 tarihinde başlıyor.
Berk Akademi
Ana Sayfa

C# LINQ Where ve Select Farkı Nasıl Anlaşılır?

csharp-linq-where-select-farki
Bu yazıda neler var?
  1. Where ve Select arasındaki temel fark nedir?
  2. Aynı öğrenci listesinde Where ve Select nasıl çalışır?
  3. LINQ zincirinde Where ve Select hangi sırayla kullanılmalı?
  4. Sonuç tipi ve eleman sayısı nasıl yorumlanır?
  5. ToList ve deferred execution yanılgısı nasıl çözülür?
  6. Sık Sorulan Sorular

C# LINQ Where ve Select farkı en kısa hâliyle şöyledir: Where, mevcut elemanlar arasından belirli bir koşulu sağlayanları filtreler; Select ise her elemandan yeni bir değer üretir veya yalnızca istenen alanı seçer. Bu nedenle Where genellikle elemanları elerken, Select sonuçtaki elemanların biçimini değiştirir.

Her iki metot da çoğunlukla IEnumerable<T> üzerinde kullanılır. IEnumerable, bir koleksiyondaki elemanların sırayla okunabilmesini sağlayan yapıyı ifade eder. Örneğin bir öğrenci listesinde Where her öğrenciyi kontrol eder, Select ise her öğrenci için yeni bir sonuç üretir. Lambda ifadesindeki student parametresi de o anda incelenen tek bir öğrenci nesnesini temsil eder.

Where ve Select arasındaki temel fark nedir?

student => student.Score >= 70 ifadesinde student, koleksiyondaki mevcut elemandır. Score özelliği 70 veya daha büyükse bu ifade true döndürür. Bu kullanım Where için uygundur çünkü Where’in görevi “Bu eleman sonuçta kalmalı mı?” sorusuna cevap vermektir.

Select ise doğru veya yanlış kararı vermek zorunda değildir. Örneğin student => student.Name ifadesi her Student nesnesinden bir metin üretir. Sonuçta artık öğrenci nesnelerinden değil, öğrenci adlarını taşıyan string değerlerinden oluşan bir akış elde edilir.

Metot Temel görevi Çıktının eleman sayısı Çıktı elemanlarının biçimi
Where Koşulu sağlayan elemanları filtrelemek Azalabilir, aynı kalabilir; koşula bağlıdır Genellikle kaynak koleksiyonla aynı tür
Select Elemanları dönüştürmek veya belirli alanları seçmek Genellikle kaynakla aynı sayıda Yeni bir tür veya seçilen alanın türü

Bu ayrımı pekiştirmek için C# bilgi testi içinde özellikle lambda ifadeleri ve koleksiyon işlemleriyle ilgili sorularda şu kontrolü yapabilirsiniz: “Elemanları mı eliyorum, yoksa her elemandan farklı bir sonuç mu üretiyorum?”

Aynı öğrenci listesinde Where ve Select nasıl çalışır?

Aynı öğrenci listesinde Where ve Select nasıl çalışır?

Aşağıdaki örnekte tek bir List<Student> üzerinden önce notu 70’in üzerinde olan öğrenciler filtreleniyor, ardından bu öğrencilerin yalnızca adları seçiliyor:

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

class Student
{
    public string Name { get; set; }
    public int Score { get; set; }
}

var students = new List<Student>
{
    new Student { Name = "Ayşe", Score = 85 },
    new Student { Name = "Mert", Score = 68 },
    new Student { Name = "Ece", Score = 92 }
};

var successfulNames = students
    .Where(student => student.Score > 70)
    .Select(student => student.Name)
    .ToList();

foreach (var name in successfulNames)
    Console.WriteLine(name);

Beklenen çıktı:

Ayşe
Ece

Bu zinciri üç adımda teşhis edebilirsiniz:

  1. Where(student => student.Score > 70), listedeki her Student nesnesini kontrol eder. Mert’in notu koşulu sağlamadığı için elenir. Kalan sonuç hâlâ Student nesnelerinden oluşur.
  2. Select(student => student.Name), kalan her Student nesnesinden yalnızca Name alanını alır. Bu aşamadan sonra sonuç tipi Student değil, string değerleridir.
  3. ToList(), oluşan sorgu sonucunu bir listeye dönüştürür ve bu liste successfulNames değişkenine atanır.

“Where kullandım ama asıl liste değişmedi” düşüncesi çoğunlukla burada ortaya çıkar. LINQ metotları genellikle kaynak listeyi yerinde değiştirmez; bunun yerine yeni bir IEnumerable sonucu üretir. Sonucu bir değişkende tutmazsanız veya zincirin sonuna ToList() ekleyip atama yapmazsanız, filtrelenmiş sonucu daha sonra kullanamazsınız. C# video eğitimleriyle çalışırken benzer örneklerde hem ara değişkenin hem de sonucun türünü gözlemlemek, Where ile Select’in görevini ayırmayı kolaylaştırır.

LINQ zincirinde Where ve Select hangi sırayla kullanılmalı?

LINQ zincirinde Where ve Select hangi sırayla kullanılmalı?

LINQ metot zincirinde yaygın ve anlaşılır yaklaşım, önce hangi elemanların kalacağını Where ile filtrelemek, ardından kalan elemanlardan hangi bilginin alınacağını Select ile belirlemektir. Böylece her adımın görevi netleşir: Where nesneleri seçer, Select ise seçilen nesnelerin görünümünü değiştirir.

var students = new List<Student>
{
    new Student { Name = "Ayşe", Score = 85 },
    new Student { Name = "Mert", Score = 60 },
    new Student { Name = "Zeynep", Score = 92 }
};

var successfulNames = students
    .Where(student => student.Score > 70)
    .Select(student => student.Name)
    .ToList();

Console.WriteLine(string.Join(", ", successfulNames));
// Beklenen çıktı: Ayşe, Zeynep

public class Student
{
    public string Name { get; set; }
    public int Score { get; set; }
}

Burada student lambda parametresi, zincirin o adımında incelenen tek bir Student nesnesini temsil eder. Where(student => student.Score > 70) ifadesi puanı 70’ten büyük öğrencileri bırakır. Sonraki Select(student => student.Name) ifadesi ise her öğrenci nesnesini bir string değere dönüştürür.

Sıra tersine çevrilirse zincirin üzerinde çalıştığı tür de değişir:

// Yanlış sıra:
var result = students
    .Select(student => student.Name)
    // .Where(student => student.Score > 70); // Hata

// Doğru sıra:
var result = students
    .Where(student => student.Score > 70)
    .Select(student => student.Name);

Select sonrasında artık Student nesneleri değil, öğrenci adlarını taşıyan string değerleri vardır. Bu nedenle sonraki adımda student.Score gibi bir özelliğe erişilemez. Zinciri teşhis ederken şu soruları sırayla sorun:

  • Koşul doğru mu? Filtre, beklediğiniz puan aralığını gerçekten ifade ediyor mu?
  • Select hangi türü üretiyor? Sonuç hâlâ Student mı, yoksa string veya anonim bir nesne mi?
  • Zincirin sonunda hangi değişkene atama yapılıyor? Değişkenin beklenen türüyle sorgunun ürettiği tür uyumlu mu?

Sonuç tipi ve eleman sayısı nasıl yorumlanır?

Bir LINQ ifadesini anlamak için sonucu üç açıdan inceleyin: tür, eleman sayısı ve eleman içeriği. Where genellikle kaynak koleksiyonun eleman türünü korur; Select ise seçtiğiniz ifadenin türüne göre yeni bir görünüm oluşturur.

İfade Sonuç türü Eleman sayısı Eleman içeriği
students.Where(...) IEnumerable<Student> Azalabilir Filtreyi geçen öğrenci nesneleri
students.Select(s => s.Name) IEnumerable<string> Genellikle kaynakla aynı Öğrenci adları

Where, koşulu sağlamayan elemanları çıkardığı için Count değeri azalabilir. Select ise normal kullanımda her kaynak elemanı için bir sonuç üretir; ancak sonuçların değerleri aynı olabilir. Örneğin iki öğrencinin adı aynıysa sonuç listesinde aynı metin iki kez bulunabilir.

SelectMany ise bir elemanın içinde birden fazla değer taşıyan başka bir koleksiyon bulunduğunda, bu iç koleksiyonları tek bir düz akışta birleştirir. Örneğin öğrencilerin ders listelerini tek akışta almak için kullanılabilir. Basit bir öğrenci listesinden yalnızca Name alanını seçmek ise SelectMany gerektirmez.

Bu ayrımı pekiştirmek ve koleksiyon türleriyle ilgili temel C# seviyenizi ölçmek için C# bilgi testi üzerinden Where ve Select sorularını değerlendirebilirsiniz.

  • Tür: Sonuç IEnumerable<Student> mı, IEnumerable<string> mi?
  • Eleman sayısı: Where kaç öğeyi eledi, Select kaç sonuç üretti?
  • İçerik: Sonuçta nesneler mi, alan değerleri mi, yoksa iç içe koleksiyonlar mı var?

ToList ve deferred execution yanılgısı nasıl çözülür?

Where ve Select, kaynak List<Student> nesnesini yerinde değiştirmez. Bu metotlar, çalıştırılmak üzere bir LINQ sorgusu oluşturur. Sorgu; üzerinde dolaşıldığında, örneğin foreach ile okunduğunda veya ToList() çağrıldığında değerlendirilebilir. Bu davranışa deferred execution, yani ertelenmiş çalıştırma denir.

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

var students = new List<Student> { new("Ada", 85), new("Mert", 45) };
var passingQuery = students.Where(s => s.Grade >= 50);
Console.WriteLine(students.Count);              // 2
Console.WriteLine(passingQuery.Count());        // 1
var fixedResult = passingQuery.ToList();
Console.WriteLine(fixedResult.Count);            // 1

record Student(string Name, int Grade);

Burada s lambda parametresi, o anda değerlendirilen tek bir öğrenci nesnesini temsil eder. passingQuery oluşturulduğunda kaynak listeden öğrenci silinmez. ToList() ise sorgunun o andaki sonucunu yeni bir List<Student> içinde somutlaştırır.

Bu süreci aynı liste üzerinden şu şekilde teşhis edebilirsiniz:

Aşama Ne ifade eder?
Kaynak liste Tüm öğrencileri içeren özgün List<Student> nesnesidir.
Where sonucu Koşulu sağlayan öğrencileri üreten, henüz kaynak listeyi değiştirmeyen sorgudur.
Select sonucu Öğrencilerin seçilen alanlarını veya yeni biçimlerini üreten sorgudur.
ToList ile sabitlenmiş sonuç Sorgunun değerlendirildiği andaki çıktının yeni bir liste kopyasıdır.

Örneğin kaynak listeye sorgu oluşturulduktan sonra yeni bir öğrenci eklenirse, henüz ToList() çağrılmamış sorgu bu değişikliği değerlendirme sırasında görebilir. Buna karşılık ToList() ile sabitlenmiş sonuç, çağrı anındaki elemanları içerir. Ancak bu işlem kaynak listedeki elemanları otomatik olarak silmez; yalnızca ayrı bir sonuç listesi üretir.

  • Kaynak değişmedi mi? Sorgunun filtreleme yaptığını, kaynağı düzenlemediğini kontrol edin.
  • Güncel veri mi gerekiyor? Sorguyu tekrar değerlendirin.
  • O anki sonucu korumak mı istiyorsunuz? ToList() ile somut bir sonuç oluşturun.

Sık Sorulan Sorular

Where kullandığım hâlde kaynak List<Student> neden değişmiyor?

Çünkü Where kaynak listedeki elemanları silmez veya düzenlemez. Yalnızca koşulu sağlayan elemanları üreten bir sorgu oluşturur. Filtrelenmiş sonucu ayrı bir değişkende kullanmanız gerekir.

Select kullandıktan sonra neden Student yerine string türünde bir sonuç elde ediyorum?

Select, her Student nesnesini seçtiğiniz başka bir değere dönüştürür. Select(s => s.Name) yazarsanız sonuç elemanları string olur; çünkü artık öğrencinin tamamını değil, yalnızca ad alanını alırsınız.

Where ve Select aynı zincirde hangi sırayla yazılmalı?

Genellikle önce Where ile ihtiyaç duyduğunuz öğrencileri filtrelemek, ardından Select ile bu öğrencilerden gerekli alanları almak daha anlaşılırdır. Böylece dönüşüm adımı yalnızca seçilen kayıtlar üzerinde tanımlanır.

ToList çağırmak LINQ sorgusunu ve kaynak koleksiyonu nasıl etkiler?

ToList(), sorguyu o anda değerlendirir ve sonucu yeni bir listeye dönüştürür. Kaynak List<Student> üzerinde otomatik silme, ekleme veya düzenleme yapmaz.

SelectMany ile Select arasındaki temel fark nedir?

Select her eleman için tek bir sonuç üretir. SelectMany ise her elemanın içinde bulunan koleksiyonları tek bir düz koleksiyonda birleştirir. Örneğin öğrencilerin ders listelerini almak için SelectMany kullanılabilir.

Bu ayrımı çözerken önce kaynağın değişip değişmediğini, sonra sorgunun ne zaman değerlendirildiğini ve son olarak sonuç elemanlarının türünü kontrol etmek en güvenilir yaklaşımdır.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin — Yazılım Geliştirici ve Eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; bugün öğrencinin seviyesine ve hedefine göre şekillenen sürdürülebilir öğrenme sistemleri tasarlıyor. 500'den fazla kişiye ezber değil, düşünerek kod yazmayı öğretti — Berk Akademi'de izlemeye değil üretmeye dayalı öğrenme kültürünü o kuruyor.

WhatsApp Hemen Ara