Published on

C# Delegate Nedir ? Nasıl Kullanılır ?

Authors
  • avatar
    Name
    Alperen Önal
    Twitter
delegate c#

Delegate c’deki fonksiyon ‘pointer’larının c#‘taki karşılığıdır denilebilir.

Delegate‘ler metotların bellekteki adreslerini tutan yapılardır.Tanımladığımız 1 delegate ile 1’den fazla metot’un adresini tutabiliriz.

Eğer 1 delegate‘de birden fazla metot’un adresini tutmak istiyorsak , delegate‘yi tanımlarken şablonu buna göre oluşturmalıyız , yani dönüş tipi ve parametreleri aynı olan metotları bir delegate içinde tutabiliriz.

Şu şekilde tanımlanır :

public delegate void MyDelegate(); //dönüş tipi void olan ve parametre almayan metotları tutabilir.

Şimdi tanımladığım delegate tipinde bir değişken oluşturup bu değişkenin “funct_1” isimli bir metot’u referans etmesini sağlıyorum.Ve artık bu değişkenimi funct_1 metot’u gibi çalıştırabiliyorum.

class Program
{

    public delegate void MyDelegate(); //dönüş tipi void olan ve parametre almayan metotları tutabilir.
    public static void Main()
    {
        MyDelegate my;
        my = Test.funct_1;  //my değişkeni artık funct_1'i referans ediyor.
        my(); //burası çalışacak ve "ben funct_1" çıktısını verecektir.
    }
}
class Test{
    static public void funct_1()
    {
        Console.WriteLine("ben funct_1");


    }

}

Üstte dediğim gibi birden fazla metot yapısını referans etmesini istiyorsam ‘+=’ ı kullanabiliriz**.**

class Program
{

    public delegate void MyDelegate(); //dönüş tipi void olan ve parametre almayan metotları tutabilir.
    public static void Main()
    {
        MyDelegate my;
        my = Test.funct_1;
        my += Test.funct_2; //artık bunu da referans et dedim.
        //my-=Test.funct_1  yazarsam ,  bunu artık referans etme demiş olurum.
        my(); //çıktısı  "ben funct_1" ve "ben funct_2 olacaktır"
    }
}
class Test{
    static public void funct_1()
    {
        Console.WriteLine("ben funct_1");


    }
    static public void funct_2()  //aynı şablona sahip 2.bir metot tanımladım.
    {
        Console.WriteLine("ben funct_2");


    }

}

Parametreli delegate tanımlamak istiyorsak , tanımlanırken referans edeceği metotların şablonunu belirterek tanımlıyoruz.

    public delegate int MyDelegate(int x,int y); //dönüş tipi int olan ve 2 adet int parametresi olan metotları referans edebilen delegate.

public delegate int MyDelegate(int x,int y); //dönüş tipi int olan ve 2 adet int parametresi olan metotları referans edebilen delegate.

Aşağıdaki örnekte çıktı 1 olacaktır.Bunun nedeni “my+=Test.funct_2” yaptığımız tanımlama ile funct_2‘yi delegatenin 2. kısmına geçiriyoruz böylelikle önce funct_1 sonra funct_2 metotları çalışıyor fakat en son funct_2‘nin degeri döndürüldüğü için onun değeri ekranda çıktı olarak yazılıyor.

class Program
{

    public delegate int MyDelegate(int x,int y); //dönüş tipi int olan ve 2 adet int parametresi olan metotları referans edebilen delegate.
    public static void Main()
    {
        MyDelegate my;
        my = Test.funct_1;
        my+=Test.funct_2;

        Console.WriteLine(my(5,4)); // çıktısı "1" olacaktır.

    }
}
class Test{
    static public int funct_1(int a,int b)
    {
        return a + b;


    }
    static public int funct_2(int c,int d)
    {
        return c - d;


    }

}

Üstteki örnekte eğer ben sadece funct_1‘in veya sadece funct_2‘nin çalışmasını istiyorsam ya da az önceki gibi değerlerden sadece bir tanesini görmek yerine 2’sinin de değerleri görmek istiyorsam,System kütüphanesi içerisindeki “Delegate[]” ile bir bir array oluşturarak istediğimi çalıştırabilirim.

class Program
{

    public delegate int MyDelegate(int x,int y); //dönüş tipi int olan ve 2 adet int parametresi olan metotları referans edebilen delegate.
    public static void Main()
    {
        MyDelegate my;
        my = Test.funct_1;
        my+=Test.funct_2;
        Delegate[] arrayDelegate= my.GetInvocationList(); //Delegate array'i tanımlıyoruz ve my'in içindeki referansları array'in içine yolluyoruz.
        Console.WriteLine(arrayDelegate[0].DynamicInvoke(4,2));  //çıktısı "6"dır.

    }
}
class Test{
    static public int funct_1(int a,int b)
    {
        return a + b;


    }
    static public int funct_2(int c,int d)
    {
        return c - d;


    }

}

Üstteki örnekte arrayDelegate[0] ile ilk referansı seçiyoruz ardından DynamicInvoke() ile mevcut ilgili ‘delegate‘i parametreleri girerek dinamik olarak çağırıyoruz.

Delegate konusu bu kadardı zaman ayırdığınız için teşekkürler.