22 Ağustos 2020 Cumartesi

Action Func Predicate

    S.A. Arkadaşlar,

    Bugünkü yazımızda Action<T>, Func<TParam,TReturn> ve Predicate<T,bool> yapıları üzerinde durmak istiyoruz. Nedir, neden ve nasıl kullanılır gibi soruların cevabını arayacağız. Aralarında ne gibi farklılıklar ve benzerlikler olduğunu söyleyip yazıyı bitirmeyi düşünüyoruz.

     Öncelikle delege (bu konunun temelini ele alan, eski ama çok güzel birkaç Burak Selim Hoca yazısı bırakacağım aşağıya. Şiddetle okumanızı tavsiye ederim) konusunu bilmeden anlaşılması zor bir konu olacağını önceden belirtmek isterim. Delege kısaca metodların referans yoluyla yerlerini tutan yapılardır. Benzer imzalarda bulunmak şartıyla birden fazla imza da tutabiliyoruz. C# 3.0 versiyonundan sonra özellikle linq’un gelişimiyle kullanımı oldukça yaygınlaştı ve bir o kadar da kolaylaştı. Bilenler için belki C’deki pointer yapısına benzetebiliriz, fakat burada type-safe olarak kullanılmaktadır.

     Aralarında en temel farkı kısaca açıklayacak olursa; Action dönüş tipi olmayan (void), Func dönüş tipi generic olan, Predicate ise dönüş tipi bool olan özel delege yapılarıdır. 16'ya kadar parametre alabilirler. Ufak hilelerle bunu daha da artırabiliyoruz. 

    Action’lar aracılığıyla metodları parametre olarak verme olanağı sağlanır, fakat burada her hangi bir sonuç dönmeyecektir. Bunu şu şekilde açıklarsak belki daha net olacaktır. 

public void ForEach(Action<T> action);

    Burada Foreach void olan bir delegedir. Burada gerekli işlemler yapılır ve işlem sonuçlanır. Normal bir foreach döngüsünden mantık olarak bir farkı yoktur. Orada da foreach paranteziyle birlikte işlemimizi tamamlamış oluruz.

var nameList = new List<string>()
{
"Malik",
"Masis",
"Algomedi"
};
Action<string> action = new Action<string>(Display);
nameList.ForEach(action);//1.
void Display(string name)
{
Console.WriteLine(name);
}
nameList.ForEach(delegate (string name) //2.
{
Console.WriteLine(name);
});

     Yukarıdaki kodda 1.tanımlama ile action yapısını foreach içerisine parametre olarak geçtik. 2.tanımlama şeklinde ise anonymous metod tanımı kullanılmaktadır.

     Func ile benzer işlemleri yapabiliyoruz, fakat dönüş tipi de döndürebiliyoruz. Örneğin; bir liste üzerinde çalışıyoruz ve orada her hangi bir değer üzerinde işlem yapıp bunu geri döndürmemiz isteniyor. Doğal olarak o listeyi tekrar döndürmemiz gerekecektir. Bu sadece bir örnek yoksa daha bir çok sonuç döndüren işlemlerle birlikte kullanılmaktadır. 

Func<string, string> selector = str => str.ToUpper();
IEnumerable<string> upperNameList = nameList.Select(selector);
foreach (var word in upperNameList)
Console.WriteLine(word);

       Yukarıda belirttiğimiz gibi gelen listedeki değerlerini hepsini büyük karaktere çevirip tekrardan liste olarak döndürdük. Başka bir örnekte bu değerleri sayıp int olarak da dönebilirdik. Örnekler artırılabilir.

     Şimdi ise Predicate konusuna gelelim. Aslında Predicate özel bir Func delegesidir. Şöyle ki her zaman bool döndürür. Filtreleme veya select işlemlerinde yoğun olarak kullanılır. Şöyle ki, liste elimize geldi ama biz sadece karakter uzunluğu 5'ten fazla olanları istiyoruz.

Predicate<string> predicate = FindBigLength;
IEnumerable<string> bigNameList = nameList.FindAll(predicate);
foreach (var word in bigNameList)
Console.WriteLine(word);
private bool FindBigLength(string name)
{
return name.Length > 5;
}

    Burada Predicate zaten bool dönüş tipinde olacağından bunu belirtme ihtiyacı duymuyoruz. Burada ve diğer delegeler için birden fazla kullanım mevcuttur, bizler sadece birkaçı üzerinde durduk.

     Konuyu özetlemek gerekirse bu delegeler sayesinde işlemlerimizi çok daha basit ve pratik halde yapabiliyoruz. Yukarıda da belirttiğimiz gibi özellikle linq kullanımı yaygınlaştıkça kullanımı çok daha kolay oldu. Bu da maalesef bu tarz yapıları kullanırken arka planda neler yapıldığını gözden kaçırmamıza sebep oluyor. Bir farkındalık uyandırabilme dileğiyle.

     Soyutlamalara rağmen arka planı gözden kaçırmamak dileğiyle.

Kaynakça

Deletege Kavramına Giriş

C# 2.0 ile Delegate Kavramı

Derinlemesine Lamda İfadeleri (Uzun süre okuduğum ve beni çok etkileyen konuyla alakalı bir yazı)

https://docs.microsoft.com/tr-tr/dotnet/api/system.collections.generic.list-1.foreach?view=netcore-3.1

https://docs.microsoft.com/tr-tr/dotnet/api/system.func-2?view=netcore-3.1

https://docs.microsoft.com/tr-tr/dotnet/api/system.predicate-1?view=netcore-3.1

https://www.infoworld.com/article/3057152/how-to-work-with-action-func-and-predicate-delegates-in-csharp.html


Hiç yorum yok:

Yorum Gönder