جواد مهدی‌نیا 1325 0 کامنت 1401/2/10

آموزش Generic Collection List در #C

Generic Collection List‌ها در زبان برنامه نویسی سی‌شارپ پر استفاده هستند. کالکشن‌ها شامل مجموعه‌ای از مقادیر یا انواع داده هستند.

کلکسیون جنریک لیست

کلکسیون داده چیست؟

کلکسیون داده شامل مجموعه‌ای از داده است که در زبان سی‌شارپ برای ذخیره‌سازی آنها استفاده می‌شود. کلکسیون به دو دسته جنریک و غیر جنریک تقسیم بندی می‌شود. از جمله کلکسیون‌های غیر جنریک می‌توان ArrayListها، Sorted Listها، Stackها، Queueها، BitArrayها و Hashtableها را می‌توان نام برد؛ اما در اینجا و در ادامه این مقاله آموزشی، می‌خواهیم به کلکسیون‌های جنریک لیست بپردازیم.

جنریک لیست چیست؟

جنریک لیست در واقع مجموعه‌ای از داده‌هایی که معمولا یک نوع مشخص یا یک نوع Data Type معین دارند را شامل می‌شود. خب برای کار با لیست‌های جنریک، لازم است که با برخی از متدهای آن آشنا شویم. جنریک لیست عناصر یک نوع مشخص را ذخیره میکند و برخلاف آرایه‌های معمول، اندازه آن به صورت خودکار تغییر می‌کند.

برای تعریف یک لیست باید نوع داده‌ای لیست را در داخل <> در جلوی List بنویسیم و به شکل زیر عمل کنیم. دقت کنید که نوع داده می‌تواند یک Data Type ساده مثل int و string باشد؛ یا اینکه قدری پیچیده‌تر بوده و شامل انواع کلاس‌ها و … نیز باشد. در مثال زیر لیست اول شامل، مجموعه‌ای از اعداد صحیح است و لیست دوم شامل مجموعه‌ای از کلاس Customer که خود این کلاس Customer شامل چندین Property مانند Id، Name، Salary و … ممکن است بشود. یک کلاس فرضی Customer را در این قسمت ایجاد کردیم که شامل چند Property است:

public class Customer
{
     public int Id { get; set; }
     public string Name { get; set; }
     public int Age { get; set; }
     public int Salary { get; set; }
}

تعریف متغیرها برای جنریک‌لیست به شکل زیر است:

List<int> myList = new List<int>();

List<Customer> myCustomerList = new List<Customer>();

البته می‌توان به جای List اول از IList هم استفاده کرد؛ در هر حال List دارای متدهای کمکی بیشتری نسبت به IList است.

متدهای Generic List ها

در این بخش متدهای مهم Generic List ها که کاربردی هستند را برای شما به همراه مثال توضیح خواهیم داد.

متد Add

متد Add برای افزودن یک آیتم به انتهای یک لیست جنریک به کار می‌رود. برای مثال لیست زیر را ببینید و نحوه استفاده از متد ADD را مشاهده کنید. برای مثال مثال زیر را ببینید:

Customer customer1 = new Customer();
Customer customer2 = new Customer();

List<int> myList = new List<int>();
List<Customer> myCustomerList = new List<Customer>();

myList.Add(5);
myList.Add(15);

myCustomerList.Add(customer1);
myCustomerList.Add(customer2);

البته در مثال بالا ما customer1 و custome2 را جهت جلوگیری از طولانی شدن کدها، مقداردهی نکردیم که همانطور که می‌دانید، در شرایط واقعی، این‌ها مقداردهی می‌شوند.

متدد AddRange

متد AddRange برای افزودن یک رنج از داده (یک لیست از داده) به انتهای یک لیست به کار می‌رود. همانطور که در متد قبلی دیدید، آن متد فقط برای افزودن یک داده بود.

 List<int> myIntList = new List<int>();
 List<int> mySubIntList = new List<int>();

 List<Customer> myCustomerList = new List<Customer>();
 List<Customer> mySubCustomerList = new List<Customer>();

 Customer customer1 = new Customer();
 Customer customer2 = new Customer();

 mySubIntList.Add(5);
 mySubIntList.Add(15);

 mySubCustomerList.Add(customer1);
 mySubCustomerList.Add(customer2);

 myIntList.AddRange(mySubIntList);
 myCustomerList.AddRange (mySubCustomerList);

چیزی که اهمیت دارد، اینست که لیست اضافه شده با متد AddRange باید از نوع همان لیستی باشد که قرار است به آن اضافه شود.

متد GetRange

اگر بخواهیم به یک تنها عنصر از یک لیست جنریک دست پیدا کنیم، می توانیم به شکل زیر عمل کنیم. البته ابتدا مثلا فرض کنید که میخواهیم در لیست مرتب mySubCustomerList، به دومین عنصر آن که مسلما از نوع کلاس Customer است و property های آن از قبل مشخص شده است دست پیدا کنیم. روش کار استفاده از اندیس آن به شکل زیر است:

 Customer customer = mySubCustomerList[1];

البته شما ممکن است به یک property خاص از کلاس Customet دستیابی پیدا کنید که در این صورت کافی است که پس از دریافت مشخصات مشتری با یک نقطه و سپس توسط نام آن property، به آن دسترسی پیدا کنید. فقط دقت کنید که نوع متغیر را هم در سمت چپ، با توجه به نوع آن property تغییر دهید.

این روش که ما به کار بردیم تنها برای دسترسی به یک Customer بود. اما اگر بخواهیم به یک محدوده یا رِنج از مشتری‌های موجود در یک لیست دسترسی پیدا کنیم چه؟ در این حال باید از متد GetRange استفاده کنیم. به این منظور پس از نوشتن نام متد، در داخل پرانتز، ابتدا شماره اندیس مدنظر را می‌نویسیم و سپس یک ورودی دیگر هم وارد می‌کنیم که عبارت است از تعداد آیتم‌هایی که می‌خواهیم. مثال زیر را ببینید:

List<Customer> selectedCustomers = myCustomerList.GetRange(1, 3);

یعنی با استفاده از کد بالا، ما یک محدوده سه تایی از Customerها را که از دومین آیتم (اندیس یکم) شروع می‌شوند، را انتخاب کردیم. همانطور که می‌دانید، در زبان‌ها برنامه نویسی آیتم‌های موجود در یک لیست و آرایه از 0 به بالا شماره گذاری می‌شوند.

متد InsertRange

اگر بخواهیم یک آیتم را به عنوان اندیس خاصی به یک لیست اضافه کنیم از متد Insert استفاده می‌کنیم و ابتدا اندیس و سپس آیتمی که قرار است اضافه شود را به آن پاس می‌دهیم. اما چنانچه بخواهیم یک لیست از همان نوع را به لیست موجود اضافه کنیم که از اندیس خاصی شروع شود، از متد InsertRange استفاده می‌کنیم و در ابتدا شماره اندیس و سپس آن لیستی که قرار است اضافه شود را قرار می دهیم. مثال‌  زیر را ببینید:

List<Customer> myCustomerList = new List<Customer>();

Customer customer1 = new Customer();
Customer customer2 = new Customer();

myCustomerList.Add(customer1);
myCustomerList.Add(customer2);

Customer addedCustomer = new Customer();

List<Customer> myAddedCustomerList = new List<Customer>();

myCustomerList.Insert(2, addedCustomer);
myCustomerList.InsertRange(0, myAddedCustomerList);

مواردی که در بالا توضیح دادیم را در دو خط انتهایی مثال بالا مشاهده می‌کنید که یکی برای افزودن یک تک آیتم و دیگری برای افزودن یک محدوده یا رنج از اندیس صفرم که شامل لیستی از Customerهاست، استفاده شده است.

متد RemoveRange

اگر بخواهیم آیتم یا آیتم‌هایی را از یک لیست حذف کنیم، می‌توانیم از Remove یا RemoveRange استفاده کنیم.

 List<Customer> myCustomerList = new List<Customer>();

 Customer customer1 = new Customer();
 Customer customer2 = new Customer();

 myCustomerList.Add(customer1);
 myCustomerList.Add(customer2);

 Customer cust = myCustomerList[1];

 myCustomerList.Remove(cust);
 myCustomerList.RemoveRange(0, 2);

همانطور که می‌بینید با استفاده از Remove یک آیتم را حذف کردیم و با استفاده از RemoveRange یک محدوده (شامل دو آیتم) از Customerها که از اندیس 0 شروع می‌شود، حذف می‌گردد. البته برای حذف یک آیتم در یک اندیس مشخص می‌توان از RemoveAt  و سپس قرار داده شماره اندیس در داخل پرانتز هم استفاده کرد. در صورتی که کل آیتم‌های یک لیست را که با شرط مشخصی سازگار هستند را بخواهیم حذف کنیم، از متد RemoveAll باید استفاده کنیم. برای مثال کدهای زیر را ببینید:

 myCustomerList.RemoveAll(x => x.Name == "Ali");

همانطور که مشاهده می‌کنید، در این مثال ما از متد RemoveAll برای حذف آن دسته عناصری از لیست myCustomerList استفاده کردیم که نام آنها برابر با Ali است. برای اعمال دستور شرطی از Linq و Lambda استفاده می‌کنیم که در داخل پرانتز دیده می‌شود و چنانچه با آن آشنایی نداشته باشید، نگران نباشید و به زودی در وبسایت نیوسان‌وب، آموزش‌های لازم در خصوص آنها ارائه خواهد شد.

بد نیست این نکته هم ذکر کنیم که برای پیمایش بین آیتم‌های یک لیست جنریک، از حلقه foreach می‌توان استفاده کرد. برای مثال حلقه زیر را ببینید.

foreach (Customer customer in myCustomerList)
{
   Console.WriteLine($"Id: {customer.Id}, Name: {customer.Name}, Age: {customer.Age}");
}

این هم بدانید که متد Clear برای حذف تمام عناصر یک لیست به کار می‌رود.

متد TrueForAll

متد TrueForAll بررسی می‌کند که آیا شرط مشخص برای تمام المان‌ها یا عناصر موجود در یک لیست برقرار است یا خیر. اگر برقرار باشد، true و در غیر این صورت، false را بر می‌گرداند. به عنوان زیر کدهای زیر را ببینید که از یک لیست اعداد صحیح، بررسی می‌کند که آیا تمام المان‌هی این لیست شامل اعداد زوج هستند یا خیر. همانطور که مشخص است، خروجی این کد false است؛ چرا که شامل عدد 5 است که فرد است.

List<int> myList = new List<int>() { 20, 5, 60, 82 };

bool result = myList.TrueForAll(m => m % 2 == 0);
Console.WriteLine(result);

جمع‌بندی و نتیجه گیری

در این مقاله آموزشی در خصوص لیست‌های جنریک توضیحات لازم را برای برنامه‌نویسان C# و طراحان وب توسط ASP.Net Core دادیم. همچنین به معرفی برخی از متدهای لازم برای کار با این لیست‌ها به همراه تعدادی مثال پرداختیم که امیدواریم مورد توجه دوستان و همراهان نیوسان‌وب واقع شود. در پایان یک سوال مطرح می‌کنیم که ممکن است در مصاحبه زبان سی شارپ از شما سوال شود. این سوال به این صورت است که آیا می‌توان در یک لیست مشخص، انواع مختلف (مثلا نوع int و نوع string) را همزمان ذخیره کرد؟ در خصوص این سوال فکر کنید و در صورت یافتن پاسخ، می‌توانید آن را در بخش نظرات قسمت پایین همین پست ذکر کنید.

لینک این مقاله را در شبکه‌های اجتماعی به اشتراک بگذارید.

دیدگاه خود را ثبت کنید

دیدگـاه مخاطبــان
نظری ثبت نشده است، شما اولین نفر باشید!