C# Delegate Kullanımı I - Delege Nedir?

C# dilinde delegelerin kullanım amacı metot saklamaktır. Delegeler Olay(event) tabanlı programlama ve asenkron programlama yaparken, anonim metot yazarken kullanılır. Bir diğer kullanım amacı da, bir metoda parametre olarak başka bir metot verebilmektir.

Delegate tanımlanırken şu öğeler belirtilmelidir:
* Saklanacak metot
* Eğer dönüş değeri varsa dönüş değeri
* Eğer saklanacak metodun parametreleri varsa bu parametreler

Örnek bir delege tanımı:

    delegate int MyDelegate(int x);
    MyDelegate temsilci = new MyDelegate(CalisacakMetot);

Yukarıda örnek bir delege tanımı yaptık. İlk satırda yazdığımız "delegate int" delege içerisinde saklayacağımız metodun int tipinde dönüş değeri olacağını gösteriyor. "(int x)" ise saklayacağımız metodumuzun int tipinde değer alacağını gösteriyor. Alt satıra geçersek ise "CalisacakMetot" delegemizin saklayacağı metot ismidir. Kısacası bu delege tanımı; programımızın içinde şu şekilde tanımladığımız "int CalisacakMetot(int x)" metodunu gerektiğinde çağırmak için saklıyor.

Şimdi örnek bir delege uygulaması yapalım:

    delegate int MathOperation(int x, int y);

    public class SimpleMath
    {
        public static int Add(int x, int y)
        { 
            int retVal = x +y;
            Console.WriteLine("Add : " + retVal);
            return retVal;
        }
        public static int Subtract(int x, int y)
        {
            int retVal = x - y;
            Console.WriteLine("Subtract : " + retVal);
            return retVal;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MathOperation mathOp = new MathOperation(SimpleMath.Add);
            mathOp(5,3);

            Console.ReadKey();
        }
    }

Burada "delegate int MathOperation(int x, int y);" satırıyla basit bir delege tanımı yaptık. Tanımı yaparken saklayacağı metodların dönüş tiplerinin int olması gerektiğini ve bu metodların int tipinde 2 parametre alması gerektiğini belirttik.

Daha sonra ise "MathOperation mathOp = new MathOperation(SimpleMath.Add)" bu satır ile mathOp delege nesnesi oluşturduk. Nesne örneği oluşturulurken construtor üzerinden bu delege nesnesine SimpleMath.Add metodunu saklaması için ekledik. Artık delegemiz bu metodu saklar hale geldi.

En canalıcı kısma geçersekte "mathOp(5,3)" bu şekilde delege nesnemiz üzerinden sakladığı metot olan SimpleMath.Add metoduna 5 ve 3 değerlerini verip bu metodu çalıştırdık.

Program çalıştığında çıktı 5+3'ten "Add : 8" şeklinde olacaktır.

Çıktı:



Bir delege birden fazla metot saklayabilir. "+=" ile delegeye metot ekleyebiliriz. Eklediğimiz metodlar FIFO mantığıyla ilk eklenen metoddan başlayıp sen eklenen metoda doğru sırayla çalıştırılır.

    mathOp += SimpleMath.Subtract;

programımıza bu satırı eklediğimizde artık önce Add metodu ardından Subtract metodu çalışacaktır. Şimdi çıktımız şu şekilde olacaktır.



Metod ekleyebildiğimiz gibi "-=" ile saklanan metodları silebilirizde:

    mathOp -= SimpleMath.Add;

Bu kod satırının ardından artık Add metodu çalışmıyacaktır. Çıktı artık şu şekilde olcaktır:



Bir delege tanımı yapılınca arka planda System.MulticastDelegate'den türetilmiş sealed bir class oluşturulur.

ildasm toolu ile exe'mizin içerisine bakarsanız bizim MathOperation delegemizin için de sealed bir class oluşturulmuş olduğunu görürsünüz.



Burada dikkatinizi BeginInvode, EndInvoke ve Invoke metodlarına çekmek istiyorum.

Invoke: Saklanan metodları senkron şekilde çalıştırır. Örneğimize dönersek "mathOp(5,3)" dediğimizde aslında "mathOp.Invoke(5,3)" metodu çalışıyor ve saklanan metodlarımız Invoke metodu yardımıyla sırayla çalıştırılıyor.

BeginInvoke ve EndInvoke ise asenkron işlemlerde kullanılıyor fakat bu konuya ileriki yazılarımızda incelemeye çalışacağız.

GetInvocationList: Delegemizin sakladığı metot listesini döndürür. Örnek kullanımı şu şekildedir:

            // delegenin sakladigi metodlar listeleniyor
            foreach (Delegate d in mathOp.GetInvocationList())
            {
                Console.WriteLine("Method Name: {0}", d.Method);
                //SimpleMath static oldugu icin bos gelecektir
                Console.WriteLine("Type Name: {0}", d.Target);
            }

Örnek Proje: DelegateExample.rar

0 yorum :

Yorum Gönder