با سلامی دوباره خدمت تمامی دوستان برنامه نویس ، با یکی دیگر از جلسات آموزش ASP.NET در خدمت شما دوستان هستم در جلسه گذشته درمورد نحوه مقداردهی آغازین کلکسیون ها و اشیاء در #C صحبت کردیم ، در این جلسه از اموزش ASP.NET Core با متدهای گسترش دهنده یا Extention Methods آشنا خواهید شد.
سرفصلهای پست
استفاده از متدهای گسترش دهنده (Extension Methods)
لازم به ذکر است که در این جلسه آموزشی از کلاس Product که در جلسات گذشته تعریف شده استفاده می کنم لذا به شما پیشنهاد می کنم که جلسات گذشته این فصل آموزشی را مطالعه نمایید.
کابرد متدهای گسترش دهنده روش خوبی برای افزودن متدهای جدید به کلاس هایی است که به کد آنها به صورت مستقیم دسترسی ندارید.
در پوشه Models ، یک کلاس به نام ShoppingCart.cs ایجاد کرده و سپس کدهای زیر را درون آن بنویسید :
using LearnCSharp.Models; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Collections; namespace LearnCSharp.Models { public class ShoppingCart : IEnumerable<Product> { public IEnumerable<Product> Products { get; set; } } }
کلاس ShoppingCart به عنوان یک کلاس پوششی برای کلکسیونی از اشیاء Product عمل میکند. میخواهیم به مجموع ارزش محصولات در کلاس ShoppingCart دسترسی داشته باشیم ولی به هر دلیلی ، مانند اینکه اصل کد آن در اختیارمان نباشد، نمیتوانیم محاسبه را به طور مستقیم به کلاس یاد شده اضافه کنیم در این حالت برای افزودن کارایی گفته شده میتوانیم از یک متد گسترش دهنده استفاده کنیم برای این منظور درون پوشه ی Models یک کلاس به نام MyExtentionMethods.cs ایجاد نموده و سپس کدهای زیر را درون آن بنویسید.
using LearnCSharp.Models; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Collections; namespace LearnCSharp.Models { public static class MyExtentionMethods { public static decimal TotalPrices(this ShoppingCart cartParam) { decimal total = 0; foreach (Product prod in cartParam.Products) { total += prod?.Price ?? 0; } return total; } } }
کاربرد this پیش از نخستین پارامتر ، متد را تبدیل به متدی گسترش دهنده کرده است نخستین پارامتر مشخص کنندهی کلاسی است که متد گسترشی در رابطه با آن کار میکند (در اینجا کلاس ShoppingCart) . توسط پارامتر cartParam میتوانیم به نمونه ای از Shopping Cart که متد گسترشی به آن اعمال شده است ، اشاره کنیم . بدنه ی متد ، جمع قیمتهای کالاهای موجود در ShoppingCart را (در خاصیت Product.Price) با استفاده از متغیر Total ، باز میگرداند. کد زیر کاربرد متد گسترشی ایجاد شده را در کنترلر Home نشان میدهد.
namespace LearnCSharp.Controllers { public class HomeController : Controller { public ViewResult Index() { ShoppingCart Cart = new ShoppingCart { Products = Product.GetProducts() }; decimal cartTotal = Cart.TotalPrices(); return View("Index",new string[] { $"Total:{cartTotal:C2}" }); } } }
توجه کنید که گرچه متد TotalPrices در کلاس جداگانه ای به غیر از ShoppingCart تعریف شده است . ولی میتوان آن را بر روی نمونه ای از کلاس یاد شده به صورتی به کار برد که گویی از اعضای کلاس ShoppingCart است. NET. کلاس های گسترش دهنده را در صورتی که در ناحیه دید کلاس مادر ایجاد شده باشند ، یعنی در همان فضای نام کلاس اصلی ، به راحتی پیدا می کند وگرنه میتوانید با استفاده از using فضای نام کلاس گسترشی را به آن معرفی کنید نتیجه اجرای برنامه ، خروجی زیر را در پنجره مرورگر نمایش میدهد .
Total: $323.95
کاربرد متدهای گسترش دهنده در رابطه با واسط ها
تعریف متدی گسترشی برای یک واسط این امکان را فراهم می اورد که متد را با همه ی کلاس هایی که واسط را پیاده سازی می کنند فراخوانی کنید ، در کد زیر کلاس Shopping Cart واسط <IEnumerable<Product را پیاده سازی کرده است.
namespace LearnCSharp.Models { public class ShoppingCart : IEnumerable<Product> { public IEnumerable<Product> Products { get; set; } public IEnumerator<Product> GetEnumerator() { return Products.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }
اینک می توانیم متد گسترشی را به شکل زیر تغییر دهیم .
namespace LearnCSharp.Models { public static class MyExtentionMethods { public static decimal TotalPrices(this IEnumerable<Product> products) { decimal total = 0; foreach (Product prod in products) { total += prod?.Price ?? 0; } return total; } } }
تغییر نوع نخستین پارامتر به <IEnumerable <Product به این معنی است که بدنهی متد میتواند به طور مستقیم با نمونه هایی از Product کار کند . کاربرد واسط به عنوان پارامتر به این معنی است که برای محاسبهی متغیر Total میتوان از هر کلاس مشتق شده ای از <IEnumerable <Product ، از جمله نمونه های ShoppingCart و یا آرایه ای از اشیاء Product استفاده کرد.
اجرای برنامه نشان میدهد که ورای چگونگی تهیه ی نمونه های Product ، نتیجه ی به دست آمده یکسان و به صورت زیر است :
Cart Total: $323.95 Array Total: $323.95
متدهای گسترش دهندهی فیلتر کننده
آخرین موردی که درباره متدهای گسترشی به آن می پردازیم توانایی آنها در فیلتر کردن داده های کلکسیون ها است . متدی گسترشی که پارامتری از نوع <IEnumerable <T داشته ومقداردهی برگشتی آن هم از این نوع باشد ، با به کار بردن فرمان yield میتواند عبارتی شرطی را بر روی عناصر داده های ورودی به کار بسته و خروجی فیلتر شده ای از آن داده ها را بازگرداند . کد زیر کاربرد این روش را در کلاس MyExtentionMethods نشان میدهد.
namespace LearnCSharp.Models { public static class MyExtentionMethods { public static decimal TotalPrices(this IEnumerable<Product> products) { decimal total = 0; foreach (Product prod in products) { total += prod?.Price ?? 0; } return total; } public static IEnumerable<Product> FilterByPrice(this IEnumerable<Product> productEnum, decimal minimumPrice) { foreach (Product prod in productEnum) { if ((prod?.Price ?? 0) >= minimumPrice) { yield return prod; } } } } }
متد FilterByPrice مقادیر کلکسیون دریافتی را با مقدار پارامتر minimumPrice سنجیده و مواردی که بیشتر یا مساوی آن باشد را برگشت میدهد. کد زیر چگونگی کاربرد این متد را نشان میدهد.
namespace LearnCSharp.Controllers { public class HomeController : Controller { public ViewResult Index() { Product[] productArray = { new Product {Name="Kayak" ,Price=275M}, new Product {Name="Lifejacket",Price=48.95M}, new Product {Name="Soccer bail" ,Price=19.50M}, new Product {Name="Corner flag" ,Price=34.95M}, }; decimal arrayTotal = productArray.FilterByPrice(20).TotalPrices(); return View("", new string[] { $"Array Total:{arrayTotal:C2}" }); } } }
فراخوانی متد FilterByPrices بر آرایه ای از نمونه های Product ، موجب می شود تنها مواردی که دارای قیمت بیشتر از ۲۰ دلار باشند به متد TotalPrices ارسال شده ودر محاسبه ی مجموع به کار می روند. اجرای برنامه نتیجه زیر را در پنجره مرورگر نشان میدهد .
Total: $358.90
یک پاسخ
مطلب برای من بسیار کاربردی و عالی بود درود