C# ile LINQ ve Lambda İfadeleri - 2

Lambda İfadeleri (Lambda Expressions)

   Metot-lambda ifadeleri yöntemiyle yazdığımız ikinci ifadede x => x > 3 ve   x=> x ifadeleri dikkat çekmektedir. Bu ifadeler lambda ifadeleri olarak adlandırılırlar. Peki nedir bu lambda ifadeleri? Nasıl çalışırlar? Bize ne gibi faydalar sağlarlar? Şimdi bu soruların cevaplarını arayalım.
 
   Bir lambda ifadesi aslında bir fonksiyondur. Daha doğru bir ifadeyle adsız bir fonksiyondur. Bunu daha net bir şekilde görebilmek için yukarıdaki LINQ cümlesini bir başka şekilde yazalım.

//LINQ cümlesinde kullanılacak bir metot
public bool ÜçtenBüyük(int i)
{
  return i > 3;
}

var sonuç = liste.Where(ÜçtenBüyük)
                 .OrderByDescending(x => x)
                 .Select(x => x.ToString());
   
 
  Burada .Where metoduna parametre olarak int tipinde parametre kabul eden ve bool değer döndüren bir fonksiyon aktarıyoruz. Kodumuz bu şekliyle de çalışa- caktır. Derleyici liste içindeki elemanların int tipinde olduğunu biliyor ve çalış- ma zamanında her bir eleman için ÜçtenBüyük metodunu çağırarak koşulun sağlanıp sağlanmadığını tespit edecektir. Ancak bu yaklaşım bir bölük pörçüklüğü beraberinde getirmektedir. LINQ cümlemiz kendi kendine yeten bir ifade olmaktan çıktı ve başka bir yerlerde yazılmış başka bir metoda bağımlı hale gel- di. Bunun telafisini şu şekilde yapabiliriz:

var sonuç = liste.Where( delegate(int x) { return x > 3; } )
                 .OrderByDescending(x => x)
                 .Select(x => x.ToString());


  Şimdi LINQ cümlemiz bir bütün halinde toplandı ve yukarıdaki bölük pörçüklükten arındı. Lambda ifadeleri yukarıdaki delege fonksiyonunun biraz daha kısaltılmış olarak yazılmış halidir.
 
  Aşağıdaki tablo yukarıda kullandığımız lambda ifadelerini ve bunlara eşdeğer olan delege (delegate) fonksiyonları göstermektedir. 


 
Lambda İfadesi      Eşdeğer Delege Metot
x => x > 3  
delegate(int x) {
     return x > 3;
 }
x => x     
delegate(int x) {
     return x;
}
x => x.ToString()    
delegate(int x) {
   return x.ToString();
}
 

  Lambda ifadelerini yazarken uyulması gereken kural şudur: delege fonksiyona parametre olacak ifadeler => (yani lambda) işaretinin soluna ve delege fonksi- yonun içeriğini oluşturacak ifadeler => sembolünün sağına yazılmalıdır. Bütün lambda ifadeleri mutlak suretle bir değer döndüreceğinden lambda ifadelerinin sağ taraflarında return ifadesi yazılmaz.
 
  Lambda ifadelerini daha iyi anlamak için şimdi lambda/metot yöntemiyle yazdığımız LINQ cümlesini IntelliSense kullanarak biraz daha yakından inceleyelim. 
 
  Aşağıda liste.Where metodu için Visual Studio tarafından gösterilen IntelliSense paneline bakalım.




 



NOT: Where metodu bir ekleme (extension) metot olduğundan IntelliSense panelinde gözüken this IEnumerable<int> source ifadesi liste değişkenimizi temsil etmektedir. 

  Görülebileceği üzere liste.Where metodunun iki değişik versiyonu var:
  1) Func<int,bool> tipinde bir parametre kabul eden versiyon
  2) Func<int,int,bool> tipinde bir parametre kabul eden versiyon
 
Özel bir delege yapısı olan Func yapılarını anlamak LINQ’i anlamak adına gerekli ve çok faydalı olduğundan gelin şimdi de bu yapıları tanıyalım.


 Func<T1,T2,…,Tn> Yapıları

Func<> yapısı .NET Framework 3.5 ile karşımıza çıkan çok dinamik ve pratik bir delege fonksiyon yapısıdır. Func<T1,T2,…,Tn> şeklindeki bir yapı Tn tipinde bir değer döndürecek ve T1, T2, …, T(n-1) tiplerinde parametre kabul edecek bir metodu temsil etmektedir. Aşağıdaki örnek ümit ediyoruz LINQ ve lambda ifadeleri açısından Func tipinde yapıları anlamak adına yeterli olacaktır.



//int kabul eden ve string döndüren metot 
public string Metot1(int i) 
{
  return i.ToString();
}
 
 
//int, int kabul eden ve string döndüren metot 
public string Metot2(int i1, int i2)
{
  return i1.ToString() + " " + i2.ToString();
}

//iki tane Func değişken tanımlayalım ve yukarıdaki metotları bu değişkenlere atayalım 
Func<int, string> func1 = Metot1; //int kabul eden ve string döndüren metot
Func<int, int, string> func2 = Metot2;//int, int kabul eden ve string döndüren metot

string s1 = func1(1); //Metot1’i func1 aracılığıyla çağırıyoruz
string s2 = func2(1, 2); //Metot2’i func2 aracılığıyla çağırıyoruz
 

Yukarıda iki Func tipinde fonksiyon değişkeni tanımladık ve ilgili metotları bu değişkenlere atadık. Şimdi aynı işi lambda ifadeleriyle çok daha az kod yazarak ve ayrıca metotlar tanımlamaksızın nasıl yapabiliriz bunu görelim: 

Func<int, string> func1 = i => i.ToString();
Func<int, int, string> func2 = (i, j) => i.ToString() + " " + j.ToString(); 
 
string s1 = func1(1);
string s2 = func2(1, 2);


i => i.ToString() ve (i, j) => i.ToString() + " " + j.ToString(); ifadeleriyle ayrıca metot tanımlamadan delege fonksiyonlarımızı tanımladık. Bu bize daha modüler ve dış etkenlerden bağımsız kod yazma imkanı sağladı. LINQ için son derece önemli olan delege fonksiyonlar, Func yapıları ve lambda ifadelerine bu şekilde özet bir girişin ardından bir sonraki yazımızda LINQ yolculuğumuza devam edelim.


Kaynak: F5 Dergisi
23.4.2014  kategori
5665 Okunma  kategori
Makaleden alıntı yaparken lütfen link veriniz...!
Hiç Yorum Yapılmadı.Hadi ilk yorumu sen yap!

Yorum Yaz


Site Bilgi

Sitede paylaşılan yazılar kaynak gösterilmek şartı ile heryerde paylaşılabilir.Unutmayalım! Bilgi paylaştıkça çoğalır.Herhangi bir soru,sorun,görüş yada öneriniz için bana iletişim kısmındaki formu doldurarak ya da
ekremesrefkilinc [at] gmail.com e-posta
adresinden ulaşabilirsiniz.
Tasarım ve Kodlama : Ekrem Eşref KILINÇ @2012 - 2019
Sql _Net Jquery Xml
Yukarı Çık