بیاموزید که چگونه میتوانید از مزایای نمایندگانی مانند Action، Func و Predicate برای تسهیل تماسها و افزودن انعطافپذیری به کد خود استفاده کنید.
در حالی که ارسال اشیا به عنوان آرگومان روشی استاندارد و آشنا برای فراخوانی متدها است، ارائه متدها به عنوان آرگومان برای متدهای دیگر کمتر چنین است. با این وجود، هنگام کار با مدیریت رویداد در سی شارپ، اغلب باید یک متد را به عنوان پارامتر به متد دیگری ارسال کنیم. ما این کار را با استفاده از نمایندگان انجام می دهیم.
من مروری بر نمایندگان در مقاله قبلی اینجا ارائه کردم. در این مقاله، نحوه کار با Action، Func و Predicate delegates در سی شارپ را بررسی خواهیم کرد. برای کار با نمونه کدهای ارائه شده در این مقاله، باید Visual Studio 2022 را در سیستم خود نصب کنید. اگر قبلاً نسخهای ندارید، میتوانید Visual Studio 2022 را از اینجا بارگیری کنید.
یک نماینده یک نشانگر تابع نوع ایمن است که می تواند به روشی ارجاع دهد که امضای مشابهی با امضای نماینده دارد. Delegates برای تعریف روشهای برگشت به تماس و پیادهسازی مدیریت رویداد استفاده میشود و با استفاده از کلمه کلیدی “Delegate” اعلام میشوند. میتوانید نمایندهای را اعلام کنید که میتواند به تنهایی ظاهر شود یا حتی در یک کلاس تودرتو باشد.
نمایندگان Func و Action چیست؟ چگونه می توان از آنها استفاده کرد؟
متداول ترین نمایندگان در C# عبارتند از Func delegate و Action delegate. هر دو نوع مرجعی هستند که یک روش را کپسوله می کنند. نماینده Func به روشی اشاره می کند که پارامترها را می پذیرد و مقداری را برمی گرداند. نماینده Action به روشی اشاره می کند که پارامترها را می پذیرد اما مقداری را بر نمی گرداند (یعنی void را برمی گرداند).
هر دوی این اشیاء نمایندگی صفر یا چند پارامتر خواهند داشت و ما میتوانیم از آنها با عبارات لامبدا یا روشهای ناشناس استفاده کنیم.
سینتکس ایجاد یک نمایندگی اکشن در سی شارپ
است
Action<TParameter>
میتوانیم با استفاده از کلمه کلیدی Action یک نماینده Action در C# ایجاد کنیم.
Action<string> actionDelegate = new Action<string>(DisplayText);
actionDelegate("Hello World!");
سینتکس برای اعلام یک نماینده Func در سی شارپ است
Func<TParameter, TOutput>
برای ایجاد یک تابع در C#، از کلمه کلیدی Func استفاده می کنیم.
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));
در اینجا کلاس DelegateHelper حاوی یک روش ثابت به نام GetTax است که مالیات را بر اساس حقوق خالص محاسبه و برمی گرداند و یک نماینده که به این روش اشاره می کند. یک نماینده Func برای فراخوانی روش GetTax استفاده شده است.
استفاده از Action delegates در C#
فهرست کد زیر مثال دیگری از نحوه استفاده از نماینده Action ارائه می دهد. این قطعه کد هنگام اجرا کلمه “Hello!!!” را چاپ می کند. در پنجره کنسول.
static void Main(string[] args)
{
Action<string> action = new Action<string>(Display);
action("Hello!!!");
Console.Read();
}
static void Display(string message)
{
Console.WriteLine(message);
}
استفاده از Func delegates در C#
و در اینجا مثال دوم استفاده از Func delegate در سی شارپ است. قطعه کد زیر ارزش یک حساب بازپرداخت سلامت یا HRA (محاسبه شده به عنوان ۴۰٪ حقوق اولیه) را چاپ می کند. حقوق پایه به عنوان استدلال به نماینده منتقل می شود.
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);
}
توجه داشته باشید که پارامتر دوم در اعلان نماینده Func در قطعه کدی که قبلا داده شد، نوع برگشتی روشی را که نماینده به آن اشاره میکند، نشان میدهد. در این مثال، مقدار Hra محاسبه شده به صورت دوبرابر برگردانده می شود.
استفاده از Predicate delegates در C#
یک Predicate نماینده ای است که یک یا چند پارامتر عمومی را می پذیرد و یک مقدار بولی را برمی گرداند. نمایندگان محمول معمولاً برای انجام عملیات جستجو بر اساس مجموعهای از معیارها استفاده میشوند.
در اینجا نحو یک نماینده Predicate است.
Predicate<T>
توجه داشته باشید که Predicate
کلاس موجودیت زیر را با نام مشتری در نظر بگیرید.
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; }
}
بعد، فهرستی از مشتریان ایجاد کنید و اشیایی از نوع Customer را در آن ذخیره کنید.
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 برای جستجوی دادهها استفاده کنیم.
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();
}
هنگامی که قطعه کد بالا اجرا می شود، نام “Joydip” در پنجره کنسول نمایش داده می شود.
استفاده از واریانس در نمایندگان در سی شارپ
وقتی نمایندگان خود را تعریف میکنید، میتوانید از کوواریانس و تضاد استفاده کنید تا به نماینده خود سطح بیشتری از انعطافپذیری بدهید. رویکرد کوواریانس این امکان را برای یک روش فراهم میکند تا نوع مشتقشدهتری را نسبت به تعریف تعریف شده در نمایندگی بازگرداند. با استفاده از تضاد، میتوانید روشی را تعریف کنید که آرگومانهای مشتقشده کمتری را نسبت به آرگومانهای نوع delegate بپذیرد.
قطعه کد زیر کوواریانس در نمایندگان را نشان می دهد.
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;
اکنون، دو بیانیه نمایندگی زیر را در نظر بگیرید.
public delegate void KeyEventHandler(object sender, KeyEventArgs e)
public delegate void MouseEventHandler(object sender, MouseEventArgs e)
از آنجایی که EventArgs کلاس پایه هر دو KeyEventArgs و MouseEventArgs است، میتوانید از تضاد استفاده کنید و آنها را تنها در یک کنترلر ترکیب کنید که میتواند رویدادهای کلید و ماوس را همانطور که در قطعه کد زیر نشان داده شده است، مدیریت کند.
private void MyCommonHandler(object sender, System.EventArgs e)
{
//Some code
}
نمایندگان یکی از پرکاربردترین ویژگی های زبان برنامه نویسی سی شارپ هستند. آنها به طور ایده آل برای اجرای برنامه ریزی رویداد محور مناسب هستند. در بیشتر موارد، نوع برگشتی روشی که یک نماینده به آن اشاره می کند باید با نوع مشخص شده در اعلان نماینده یکسان باشد. با این حال، میتوانیم برای دستیابی به انعطافپذیری بیشتر به کوواریانس و تضاد روی بیاوریم.
پست های مرتبط
نحوه کار با نمایندگان Action، Func و Predicate در سی شارپ
نحوه کار با نمایندگان Action، Func و Predicate در سی شارپ
نحوه کار با نمایندگان Action، Func و Predicate در سی شارپ