Nesneleri bağımsız değişken olarak iletmek, yöntemleri çağırmanın standart ve bilinen bir yolu olsa da, yöntemleri diğer yöntemlere bağımsız değişken olarak sağlamak o kadar kolay değildir. Bununla birlikte, C#’ta olay işleme ile çalışırken genellikle bir yöntemi parametre olarak başka bir yönteme geçirmemiz gerekir. Bunu delegeler kullanarak yapıyoruz.
Burada daha önceki bir makalede delegelere genel bir bakış sunmuştum. Bu yazımızda C# dilinde Action, Func ve Predicate delegeleri ile nasıl çalışabileceğimizi inceleyeceğiz. Bu makalede verilen kod örnekleriyle çalışmak için sisteminizde Visual Studio 2022 kurulu olmalıdır. Halihazırda bir kopyanız yoksa, Visual Studio 2022’yi buradan indirin.
Bir temsilci, temsilcinin imzasıyla aynı imzaya sahip bir yönteme başvurabilen, tür açısından güvenli bir işlev işaretçisidir. Temsilciler, geri arama yöntemlerini tanımlamak ve olay işlemeyi uygulamak için kullanılır ve “delegate” anahtar sözcüğü kullanılarak bildirilir. Kendi başına veya hatta bir sınıf içinde iç içe görünebilen bir temsilci bildirebilirsiniz.
İşlev ve Eylem delegeleri nedir? Nasıl kullanılabilirler?
C#’daki en yaygın temsilciler, Func temsilcisi ve Eylem temsilcisidir. Her ikisi de bir yöntemi kapsayan referans türleridir. Func temsilcisi, parametreleri kabul eden ve bir değer döndüren bir yönteme işaret eder; Eylem temsilcisi, parametreleri kabul eden ancak bir değer döndürmeyen (yani, geçersiz değer döndüren) bir yönteme işaret eder.
Bu temsilci nesnelerin her ikisi de sıfır veya çok sayıda parametre alacaktır ve bunları lambda ifadeleri veya anonim yöntemlerle kullanabiliriz.
C#’ta bir eylem temsilcisi oluşturmaya ilişkin sözdizimi şöyledir:
Action<TParameter>
Action anahtar kelimesini kullanarak C#’ta bir Action temsilcisi oluşturabiliriz.
Action<string> actionDelegate = new Action<string>(DisplayText);
actionDelegate("Hello World!");
C#’ta bir Func temsilcisi bildirmek için sözdizimi şöyledir:
Func<TParameter, TOutput>
C#’ta bir işlev temsilcisi oluşturmak için Func anahtar sözcüğünü kullanırız.
public class DelegateHelper
{
Func<double, double> functionDelegate = new Func<double, double>(GetTax);
public static double GetTax(double netSalary)
{
return (double)(netSalary * .3);
}
}
Console.WriteLine(DelegateHelper.GetTax(100000));
Burada DelegateHelper sınıfı, net maaş üzerinden vergi hesaplayan ve iade eden GetTax adlı statik bir yöntem ve bu yöntemi işaret eden bir temsilci içerir. GetTax yöntemini çağırmak için bir Func temsilcisi kullanılmıştır.
C#’ta Eylem temsilcilerini kullanma
Aşağıdaki kod listesi, bir Eylem temsilcisini nasıl kullanabileceğinize dair başka bir örnek sağlar. Bu kod parçacığı çalıştırıldığında “Merhaba!!!” kelimesini yazdırır. konsol penceresinde.
static void Main(string[] args)
{
Action<string> action = new Action<string>(Display);
action("Hello!!!");
Console.Read();
}
static void Display(string message)
{
Console.WriteLine(message);
}
C#’ta Func temsilcilerini kullanma
Ve işte C#’ta bir Func temsilcisi kullanmanın ikinci bir örneği. Aşağıdaki kod parçacığı, bir sağlık geri ödeme hesabının veya HRA’nın (temel maaşın %40’ı olarak hesaplanmıştır) değerini yazdırır. Temel maaş, delegeye argüman olarak iletilir.
static void Main(string[] args)
{
Func<int, double> func = new Func<int, double>(CalculateHra);
Console.WriteLine(func(50000));
Console.Read();
}
static double CalculateHra(int basic)
{
return (double)(basic * .4);
}
Daha önce verilen kod parçacığındaki Func temsilcisinin bildirimindeki ikinci parametrenin, temsilcinin işaret edeceği yöntemin dönüş türünü temsil ettiğini unutmayın. Bu örnekte, hesaplanan Hra değeri çift olarak döndürülür.
C#’ta Predicate temsilcilerini kullanma
Bir Tahmin, bir veya daha fazla genel parametreyi kabul eden ve bir boole değeri döndüren bir temsilcidir. Yüklem temsilcileri, genellikle bir dizi kritere dayalı arama işlemlerini gerçekleştirmek için kullanılır.
Bir Predicate temsilcisinin sözdizimi buradadır.
Predicate<T>
Predicate
Müşteri adlı aşağıdaki varlık sınıfını göz önünde bulundurun.
class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
}
Ardından, bir müşteri listesi oluşturun ve bu listede Müşteri türündeki nesneleri depolayın.
List<Customer> custList = new List<Customer>();
custList.Add(new Customer { Id = 1, FirstName = "Joydip", LastName = "Kanjilal", State = "Telengana", City = "Hyderabad", Address = "Begumpet", Country = "India" });
custList.Add(new Customer { Id = 2, FirstName = "Steve", LastName = "Jones", State = "OA", City = "New York", Address = "Lake Avenue", Country = "US" });
Aşağıda, verileri aramak için bir Predicate temsilcisini nasıl kullanabileceğimizi gösteren tam kod listesi yer almaktadır.
static void Main(string[] args)
{
List<Customer> custList = new List<Customer>();
custList.Add(new Customer { Id = 1, FirstName = "Joydip", LastName = "Kanjilal", State = "Telengana", City = "Hyderabad", Address = "Begumpet", Country = "India" });
custList.Add(new Customer { Id = 2, FirstName = "Steve", LastName = "Jones", State = "OA", City = "New York", Address = "Lake Avenue", Country = "US" });
Predicate<Customer> hydCustomers = x => x.Id == 1;
Customer customer = custList.Find(hydCustomers);
Console.WriteLine(customer.FirstName);
Console.Read();
}
Yukarıdaki kod parçacığı yürütüldüğünde, konsol penceresinde “Joydip” adı görüntülenecektir.
C# delegelerde varyansı kullanma
Temsilcilerinizi tanımladığınızda, temsilcinize daha fazla esneklik sağlamak için kovaryans ve kontravaryansı kullanabilirsiniz. Kovaryans yaklaşımı, bir yöntemin temsilcide tanımlanandan daha fazla türetilmiş bir tür döndürmesini mümkün kılar. Karşıtlığı kullanarak, temsilci türündekilerden daha az türetilmiş bağımsız değişken kabul eden bir yöntem tanımlayabilirsiniz.
Aşağıdaki kod parçacığı, delegelerdeki kovaryansı gösterir.
class TypeA {}
class TypeB : TypeA {}
public delegate TypeA MyDelegate();
public static TypeA HandlerA()
{
//Some code
}
public static TypeB HandlerB()
{
//Some code
}
MyDelegate delegateA = HandlerA;
MyDelegate delegateB = HandlerB;
Şimdi, aşağıdaki iki delege bildirimini göz önünde bulundurun.
public delegate void KeyEventHandler(object sender, KeyEventArgs e)
public delegate void MouseEventHandler(object sender, MouseEventArgs e)
EventArgs, hem KeyEventArgs hem de MouseEventArgs’ın temel sınıfı olduğundan, bunları aşağıda verilen kod parçacığında gösterildiği gibi hem anahtar hem de fare olaylarını işleyebilen tek bir işleyicide birleştirmek için kontravaryanstan yararlanabilirsiniz.
private void MyCommonHandler(object sender, System.EventArgs e)
{
//Some code
}
Temsilciler, C# programlama dilinin en yaygın kullanılan özellikleri arasındadır. Olay güdümlü programlamayı uygulamak için idealdirler. Çoğu durumda, bir temsilci tarafından işaret edilen yöntemin dönüş türü, temsilcinin bildiriminde belirtilen türle aynı olmalıdır. Ancak, daha fazla esneklik kazanmak için kovaryans ve kontravaryansa dönebiliriz.
Telif hakkı © 2023 IDG Communications, Inc.
Kaynak : https://www.infoworld.com/article/3057152/how-to-work-with-action-func-and-predicate-delegates-in-c-sharp.html#tk.rss_all