Delegate kullanımı

Delegate’ler bir metodun referansı olarak kullanılırlar. Dolayısı ile nesneleri heap’de durur. FIFO Mantığıyla çalışır.

    delegate int Matematik(int x);
    delegate void MyGenericDelegate(T args); //generic delegate
    class Program
    {
        static void Main(string[] args)
        {
            //generic delegate
            MyGenericDelegate stringDelegate = new MyGenericDelegate(StringTarget);
            stringDelegate("Safak");

            MyGenericDelegate intDelegate = new MyGenericDelegate(IntTarget);
            intDelegate(26);

            //Aşağıdaki list ile Delegenin üzerindeki metotları görebiliriz.
            Delegate[] DelegeMetodListesi = stringDelegate.GetInvocationList();

            //Action - Void türü methodlar için kullanılır, geri sonuç döndürmez.
            Action<int,string> action = new Action<int,string>(DisplayAge);
            action(28,"CEM");

            //Func - Geri değer döndüren methodlar için kullanılır.
            Func<DateTime, double> func = new Func<DateTime, double>(GetUserAgeAtTime);
            double dateDif = func(DateTime.Now.AddYears(-2));
            Console.WriteLine("\nDate Dif: {0}", dateDif);

            //Delegate
            Matematik canta = new Matematik(KareAl);
            canta += new Matematik(KupAl); // delege ekleme
            canta -= new Matematik(KareAl); // delege çıkarma
            Console.WriteLine(canta.Invoke(5)); //delege çalıştırır.

            int delegesonu = canta(3); //delege çalıştırır(canta.Invoke(3) aynı işi yapar).
            Console.ReadKey();
        }

        static double GetUserAgeAtTime(DateTime birthDate)
        {
            return (DateTime.Now - birthDate).TotalDays;
        }

        static void StringTarget(string arg)
        {
            Console.WriteLine("arg in uppercase is: {0}", arg.ToUpper());
        }
        static void IntTarget(int arg)
        {
            Console.WriteLine("++arg is: {0}", ++arg);
        }
        static void DisplayAge(int age, string name)
        {
            Console.WriteLine("Name: {0}, Age: {1}", name, age);
        }

        static int KareAl(int sayi)
        {
            return sayi * sayi;
        }

        static int KupAl(int sayi)
        {
            return sayi * sayi * sayi;
        }

    }

MVC Url.Action Metodu

Aşağıdaki yapı anımsamanız açısından Html.ActionLink metoduna örnektir.

@Html.ActionLink(“Link Adı”,”Action Adı”,”Controller Adı”)
@Html.ActionLink("homeindex", "Index", "Home")
Çıktısı: /Home/Index

Üstteki yapı sayesinde, “Home(Controller)” ismindeki Controller sınıfımızda bulunan “homeindex” isimli ActionResult tipli metodu çalıştırılıyor.
Şimdi de URL.Action metodu için örnek yapalım.

<a href=’@Url.Action(“Action Adı”,”Controller Adı”)’>Link Adı</a>

Url.Action metodunda ise, “Home(Controller)” ismindeki Controller sınıfımızda bulunan “homeindex” isimli ActionResult tipindeki metodu çalıştırıp, html deki etiketinin “href” attribute una adres yolunu veriyor. Link yapısının Html.ActionLink’ten hiç bir farkı yoktur.

<section id="languages">
@Html.ActionLink("Türkçe", "ChangeCulture", "Home", new { lang = "tr", returnUrl = this.Request.RawUrl }, null)
<span>|</span>@Html.ActionLink("English", "ChangeCulture", "Home", new { lang = "en", returnUrl = this.Request.RawUrl }, null)
</section>

Action ve Predicate nedir?

Delegate konusu içerisinde incelenebilecek,özel delegelerden olan Generic Predicate<> ve Action<> delegelerinden bahsedeceğim.

Predicate

List employees = new List();
employees.Add(new Employee("başkan", 3000));
employees.Add(new Employee("yardımcı", 2000));
employees.Add(new Employee("işçi", 100));

Böyle bir liste yaratıyoruz.Diyelim ki yönetim bizden ücreti 1500 den fazla olan çalışanların listesini istedi.

Demek ki FindAll metodu işimize yarayacak yani çalışanlarımız içerisinde istediğimiz şartı sağlayan tüm işçilerin listesini getirebilecek. Metodun aldığı parametreye bakıldığında ise Employee tipinden generic Predicate delegesi beklediğini görüyoruz. O zaman nedir bu predicate bir bakalım.Tanımı;
2
Yani Predicate<> öyle bir delege ki içerisinde generic bir parametre alan ve geriye bool döndüren metotları taşıyabilir.O halde gidip bu imzaya sahip bir metot geliştirelim.

bool Greaterthanx(Employee emp)
{
    return (emp.Salary>1500)?true:false;
}

Artık bu metodu FindAll metodu içerisinde çağırabiliriz ve sonuç kümesini yine bir listede saklayabiliriz.

results generic listinin elemanlarına bakıldığında maaşı 15000 den buyuk oyuncuların listesi olduğunu görebilirsiniz.Ayrıca yine .Net 2.0 ile gelen Anonymous Method yazım şekli ile metodu ayrı bir blokta yazmadan da FindAll metodu içerisinde çağırabiliriz.

Action 

Maaşı 15000’den fazla olan işçilerin maaşlarında %10 indirime gidilmesi istenirse?
5
Açıklamasına bakıldığında aslında tek bir metotla elimdeki listenin hepsine istediğim algoritmayı uygulayabileceğimi anlıyorum. Ama metot Employee generic parametresi alan bir Action<> delegesi istiyor. Peki yine önce bu delegeyi tanıyalım.

Baktığımızda Action delegesinin içerisine generic bir parametre alan ve geriye dönüş tipi void olan metotları taşıyabildiğini görüyoruz.O halde istediği metodu yazalım.

void Decraese(Employee emp)
{
    emp.Salary-=0.10;
}

Sonuç olarak alttaki gibi delegemizi parametre olarak kullandığımızda;
7
Artık results listesindeki çalışanların maaşlarında % 10 oranında indirime gidildiğini görebiliriz

Başka bir Action;
Action MyAction = y => Console.Write(y);
MyAction(“Hello”)