System Namespace de Tanımlı Delegate Türleri
.Net Framework içerisinde iki tür generic delegate tanımlıdır. Bunlar “Action” ve “Func” dır. Kendi oluşturmuş olduğumuz delegate tanımları yerine bunları kullanabiliriz.
- Action void değer dönderen bir delegate türünü temsil eder. Çeşitli versiyonları 0 ila 16 arasında parameter alabilir. Aşağıda görüldüğü gibi.

16’dan fazla parameter alan bir metodunuz yoksa Action türünü kullanabilirsiniz. Örnek olarak aşağıdaki iki kullanım da aynı işleve sahiptir.
// Delegate tanımı 1.
private delegate void MessageHandler(string message);
private MessageHandler messageHandler;
// Delegate tanımı 2.
private Action<string> messageHandler;
- Func istenilen bir değeri dönderen bir delegate türünü temsil eder. Çeşitli versiyonları 0 ila 16 arasında parameter alabilir. Aşağıda görüldüğü gibi.

Buradaki “TResult” parametresi delegatenin dönüş parametresidir. İhtiyaçlarınızı karşıladığı sürece Func türünü kullanabilirsiniz. Aşağıdaki iki kullanım da aynı işleve sahiptir.
// Delegate tanımı 1.
private delegate string MessageHandler(int messageCode);
private MessageHandler messageHandler;
// Delegate tanımı 2.
private Func<int,string> messageHandler;
2 – EVENTS
Event bir nesnenin, bir durum oluştuğunda program ile iletişim kurmasını sağlar. Bir olay sonucunda, bir dizi davranışın belirlenmesini sağlar. Örnek olarak; bir e-mail nesnesi bir mailin alındığını programa bildirmek için event nesnesi çağırabilir, daha temel olarak, bir buton nesnesi kullanıcının butona tıkladığını programa bildirmesi için event nesnesi çağırabilir.
İlk olarak event tanımlaması gereklidir. Aşağıdaki imza şablonuna göre event tanımlanır.
[Erişim Belirleyicisi] event [tanımlanan delegate] [event ismi];
Burada “[tanımlanan delegate]” event’in tipini belirler ve olay oluştuğunda çağrılacak metodları tanımlar.
//Delegate tanımı
public delegate void MailHandler(string text);
//Event tanımı
public event MailHandler Print;
Örnek üzerinden incelenirse:
namespace EventExample
{
class Program
{
static void Main(string[] args)
{
//Email nesnesi oluşturuyoruz.
Email email = new Email();
//Mail listesininin yazdırılacağı medotu event'e tanımlıyoruz.
email.Print += new Email.MailHandler(Display.PrintLine);
//İkinci bir metod da ekleyebiliriz.
email.Print += new Email.MailHandler(Display.PrintSideBySide);
//Mail listesi ekrana yazdırılırken Print eventinin
//Subscribe ettiği tüm medtodlar çağırılır.
email.DisplayAllMails();
}
}
class Email
{
//Delegate tanımı
public delegate void MailHandler(List<string> emailList);
//Event tanımı
public event MailHandler Print;
public List<string> DownloadAllMails()
{
return new List<string>
{
"Mail 1",
"Mail 2",
"Mail 3",
"Mail 4",
};
}
public void DisplayAllMails()
{
List<string> mailList = DownloadAllMails();
Print(mailList);
}
}
static class Display
{
public static void PrintLine(List<string> list)
{
foreach (var item in list)
Console.WriteLine(item);
}
public static void PrintSideBySide(List<string> list)
{
foreach (var item in list)
Console.Write(item + " ");
}
}
}

Önceki yazıda bahsedilen ön tanımlı, system namespacesi altında bulunan Action ve Func delegate tanımları event tanımlarken kullanılabilir.
public event Action<List<string>> Print;
Microsoft event kullanımında her bir eventin iki parametreye sahip olmasını öneriyor; ilk parametre eventi çağıran nesne, ikinci parametre event ile ilgili değerler. Bu, windows form uygulamalarından da aşina olduğumuz bir kullanım biçimidir. Bir buton nesnesinin handler methodu örnek olarak verilebilir.
private void button1_Click(object sender, EventArgs e)
{
}
.Net de bu şekilde kullanım için EventHandler isimli bir delegate tanımı bulunmaktadır. Aşağıda basit bir örneği vardır.
namespace EventExample
{
class Program
{
static void Main(string[] args)
{
ShoppingCart shoppingCart = new ShoppingCart();
shoppingCart.Discount += Display.DiscountDisplayHandler;
shoppingCart.AddProduct(new Product
{
Name = "Product 1",
Price = 200m
});
shoppingCart.AddProduct(new Product
{
Name = "Product 2",
Price = 500m
});
shoppingCart.ApplyDiscount("EYL20");
}
}
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
public class ShoppingCart
{
public event EventHandler<DiscountEventArgs> Discount;
public decimal TotalAmount { get; set; }
public List<Product> Products { get; set; }
public ShoppingCart()
{
Products = new List<Product>();
}
public void AddProduct(Product product)
{
Products.Add(product);
TotalAmount += product.Price;
}
public void ApplyDiscount(string cuponCode)
{
if (cuponCode == "EYL20")
{
TotalAmount -= TotalAmount * 0.2m;
if (Discount != null)
Discount(this, new DiscountEventArgs(cuponCode, true));
}
else
{
if (Discount != null)
Discount(this, new DiscountEventArgs(cuponCode, false));
}
}
}
public static class Display
{
public static void DiscountDisplayHandler(object sender, DiscountEventArgs args)
{
if (args.IsActive)
{
var cart = sender as ShoppingCart;
cart.Products.ForEach((a) => { Console.WriteLine($"{ a.Name} --> {a.Price}"); });
string message =
$"{args.CuponCode} is applied." + Environment.NewLine +
$"Total Amount {cart.TotalAmount}";
Console.WriteLine(message);
}
else
{
string message =
"This cupon code is not active." + Environment.NewLine +
"--> " + args.CuponCode;
Console.WriteLine(message);
}
}
}
public class DiscountEventArgs : EventArgs
{
public bool IsActive { get; set; }
public string CuponCode { get; set; }
public DiscountEventArgs(string cuponCode, bool isActive)
{
this.IsActive = isActive;
this.CuponCode = cuponCode;
}
}
}

Aşağıdaki linklerden Microsoft’un hazırlamış olduğu makalelere göz atabilirsiniz.
https://docs.microsoft.com/dotnet/csharp/programming-guide/delegates/
Güzel içerik