- Published on
C# Delegate Nedir ? Nasıl Kullanılır ?
- Authors
- Name
- Alperen Önal
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.