Func – Action – Predicate Nedir, Nasıl Kullanılır

on

Bu kavramlara değinmeden önce delegeler ile ilgili biraz bilgi vermek istiyorum.

Delegeler metodları referans eden ve referans ettikleri metodlarla aynı imzaya sahip olan yani aynı tipte parametrelere ve dönüş değerlerine sahip olan yapılardır.

Delegeler için metot referansını tutar deriz, bu tanım herkese çok açıklayıcı gelmeyebilir. Kısaca bu tanıma da değinelim. Öncelikle geri dönüş tipi ve alacağı parametreleriyle bir delege tanımlarız. Tanımladığımız bu delegenin bir instance’ını aldığımızda çağıracağı metodu söyleriz. Çağıracağı bu metot delegenin dönüş tipi ve aldığı parametreler ile aynı olmak zorundadır. Son olarak da instance’ını aldığımız delege’ye parametreleri geçeriz. Buradaki teorik bilgiyi bir örnek ile pekiştirelim.

 

Öncelikle delegeyi aşağıdaki gibi tanımlıyoruz. Generic bir tip alan ve void olan bir delege oluşturduk.

 

Sonra oluşturduğumuz bu delegenin bir instance’ını alıyoruz ve çağıracağı metodu söylüyoruz, işte “metot referansıdır” tanımı tam olarak budur. Bu delege string parametre alan ve void olan SampleMetod metodunu çağıracak.

 

Son olarak da çağıracağı metoda geçeceği parametreleri tanımlıyoruz.

 

Burada delege SampleMetod metodunu çağırıyor ama bu metodun bir önemi yok, önemli olan string parametre alan ve void olan bir metot olması yani delege ile aynı imzaya sahip olması.

 

Kodun son hali

 

Delegeleri event, thread, asenkron programlamada vb bir çok yerde kullanırız. Makalenin asıl amacı genel olarak delege yapısı olmadığı için çok fazla detaya girmeden biraz bahsetmek istedim.

Delegeler ile ilgili biraz bilgi verdikten sonra artık asıl konumuza gelebiliriz.

Func, Action ve Predicate birer delege’dirler.

 

Func

Geriye değer döndüren ve parametre alabilen delegelerdir. Biraz daha detaya indiğimizde Func‘ın 17 tane overload’u olduğunu görüyoruz. Bu yapılar oluşturulurken generic mimariden faydalanılmıştır. Yani dönüş tipleri ve parametreler konusunda tamamen özgür olabiliriz.

Object Browser’dan detayları inceleyebilirsiniz.

 

Action

Action‘ın Func‘dan farkı geriye değer döndürmemesidir. Action‘ın 16 tane overload’u vardır. Parametreler yine generic olduğu için tipler konusunda yine tamamen özgür olabiliriz.

Object Browser’dan detayları inceleyebilirsiniz.

 

Predicate

Predicate de bir delegedir. Diğerlerinden farkı ise: generic parametre alıp geriye boolean döndürmesidir. Yani Func<in T, out bool> nin yaptığı işin aynısını yapar. Farklı overloadları yoktur. Bir tane generic parametre alır ve geriye boolean döner.

 

Teorik bilgiyi verdikten sonra, nasıl kullanıldığıyla ilgili örneklere bakalım.

 

Neden delege kullanmalıyım?
Soruyu kısaca şöyle cevaplayabiliriz, metotların parametre olarak kullanılmasını istiyorsak yani, bir metodu başka bir metoda parametre olarak göndermek istediğimizde delegeleri tercih edebiliriz. Daha detaylı cevap için buraya bakabilirsiniz.

 

Func<> ların en yaygın ve basit örneği lambda expressions‘lardır.

ifadesinde, eşitliğin sol tarafı fonksiyona giden parametreleri, sağ tarafı da metodun gövdesini ifade eder.

 

Func‘lar pratikte genellikle parametre olarak kullanılırlar, c# ile geliştirme yapan herkes mutlaka Func‘ların parametre olarak çok sık kullanıldığına tanıklık etmiştir. Özellikle enumerable tipindeki datalarla çalışırken, Select, Where, Order gibi extension metotların Func‘ları parametre olarak kullandığını görmüşüzdür.

Biz de buna benzer bir örnek yapalım. IEnumerable<T> tipinde, listeyi parametre alan ve bu liste elemanları üzerinde Func ile işlem yapıp, geriye döndürdüğü değeri de Console ile ekrana yazdıran extension bir metot yazalım.

 

Metodumuzu yukarıdaki tanıma uygun bir şekilde oluşturduk. GenericPrint extension metodu iki tane parametre alıyor: birincisi üstünde işlem yapılacak liste, ikincisi işlem yapacak delege.
Parametre olarak gelen Func’ı inceleyecek olursak, generic olarak bir tane T parametresi alıyor ve yine generic olarak TResult dönüyor.

Bu metodun nasıl kullanıldığına bakalım.

Öncelikle Player isminde aşağıdaki gibi bir class oluşturalım.

 

Sonrasında yazdığımız metoda parametre olarak geçeceğimiz listeyi aşağıdaki gibi oluşturup, metodu çağıralım.

 

Yukarıdaki kodun sekizinci satırına baktığımızda, Func‘ın parametre olarak nasıl kullanıldığını görüyoruz.

ifadesinde p Func‘ın generic olarak aldığı parametre, p.Name ise Func‘ın generic olarak döndüğü parametre oluyor. Bu örnekde Player classında ki Name string bir ifade olduğu için Func‘ın string bir değer döndürmesini istemiş oluyoruz.

ifadeyi

olarak değiştirdiğimizde ise Func‘ın int değer döndürmesini istemiş oluyoruz.

 

Ekran çıktıları şu şekilde;

 

 

Kodların en son hali şöyle:

 

Yukarıda kısaca Func, Action, Predicate kavramlarına değinmeye çalıştım. Sormak istediğiniz herhangi bir şey olursa, cevaplamak isterim.

Teşekkürler.