آموزش گام به گام #C (جلسه بیستم: معرفی Generic Collectionها)
1398/01/25 11:43 , میلاد صاحب نظر

آموزش گام به گام #C (جلسه بیستم: معرفی Generic Collectionها)

آرایه‌ها علاوه بر اینکه گاهی فرشته‌های نجات هستند، گاهی هم به کابوس‌هایی از باگ‌ها و مشکلات وحشتناک برای برنامه‌نویس تبدیل می‌شوند. Generic Collectionها نه تنها توانایی انجام کارهایی بیشتر از آرایه‌ها را دارند بلکه مشکلات آن‌ها را نیز ندارند. با ما همراه باشید!

جلسه اول: آغاز کار با #C جلسه ششم: namespaceها جلسه یازدهم: اندیس گذار یا indexerها جلسه شانزدهم: استفاده از اتریبیوت‌ها جلسه بیست و یکم: متدهای بی‌نام یا anonymous
جلسه دوم: عملگرها، نوع‌ها و متغیرها جلسه هفتم: مقدمه‌ای بر کلاس‌های #C جلسه دوازدهم: ساختار یا structها جلسه هفدهم: enumها جلسه بیست و دوم: موضوعاتی در مورد نوع در #C
جلسه سوم: عبارات کنترلی - گزینشی جلسه هشتم: وراثت کلاس در #C جلسه سیزدهم: واسط یا interfaceها جلسه هجدهم: عملگرهای overloading جلسه بیست و سوم: کار با نوع‌های nullable
جلسه چهارم: عبارات کنترلی - حلقه‌ها جلسه نهم: چندریختی جلسه چهاردهم: مقدمه‌ای بر delegateها و رویدادها جلسه نوزدهم: کپسوله‌سازی  
جلسه پنجم: متدها جلسه دهم: ویژگی یا propertyها جلسه پانزدهم: مقدمه‌ای بر کنترل خطا یا exception جلسه بیستم: مقدمه‌ای بر generic collectionها  

اگر به یاد داشته باشید، در جلسه دوم در مورد آرایه‌ها آموختید و فهمیدید که آرایه‌ها به ما اجازه می‌دهند مجموعه‌ای از اشیاء را اضافه کرده یا بازگردانیم. آرایه‌ها برای انجام کارهای بسیاری مفید هستند، اما #C ورژن ۲.۰ یک ویژگی جدید به نام genericها معرفی کرد.  

Genericها مزایای بسیار زیادی دارند، اما بزرگ‌ترین و بهترین مزیت آن‌ها این است که امکان ایجاد مجموعه‌هایی را فراهم می‌کنند که به ما اجازه می‌دهند کارهای خیلی بیشتری نسبت به آنچه آرایه‌ها می‌توانند انجام دهند، انجام دهیم.

در این جلسه ما generic collectionها را معرفی خواهیم کرد و نشان خواهیم داد که چگونه می‌توان از آن‌ها استفاده کرد. اهداف ما در این جلسه عبارت‌اند از:

  • درک اینکه generic collectionها چگونه می‌توانند به ما منفعت برسانند.
  • آموختن چگونگی ایجاد و استفاده از یک لیست generic
  • نوشتن کدی که یک دیکشنری generic پیاده‌سازی کند

Genericها در #C: چه کاری می‌توانند برای من انجام دهند؟

در طول این دوره به خوبی با نوع‌ها آشنا شدید، چه نوع‌های مخصوص #C (مانند int، float و char) یا نوع‌های سفارشی (مانند Shape، Customer، Account و غیره). در NET V1.0. مجموعه‌هایی مانند ArrayList برای کار با گروه‌های اشیاء وجود داشتند.

ArrayList چیزی شبیه به یک آرایه است، به استثنای اینکه می‌تواند به صورت خودکار رشد کند و متدهای بسیار آسان و خوبی ارائه می‌دهد که آرایه از آن‌ها برخوردار نیست. مشکل ArrayList و تمام دیگر مجموعه‌های NET V1.0. این است که فقط روی شیء نوع عملیات انجام می‌دهند.

چون همه اشیاء از نوع شیء مشتق گرفته می‌شوند، پس می‌تواند هر چیزی را به یک ArrayList اختصاص دهید. مشکل این کار، این است که برنامه به خاطر تبدیل‌های زیاد اشیاء نوع مقداری به نوع شیء یا برعکس عملکرد ضعیفی خواهد داشت و یک ArrayList در طول این تبدیل‌ها،  ممکن است به صورت تصادفی نوع‌های مختلفی را در خود نگه دارد.

این امر باعث می‌شود یافتن ارورها در رانتایم بسیار مشکل باشد، چون شما کد را به گونه‌ای نوشتید که فقط با یک نوع کار کند. Generic Collectionها این مشکلات را برطرف می‌کنند.

Generic Collection یک نوع قوی (type safe) است، این بدان معنا است که فقط می‌توانید یک نوع شیء درون آن قرار دهید. این امر باعث می‌شود مشکلات اشتباه نوع در رانتایم پیش نیایند.

مزیت دیگر type safe بودن این است که عملکرد برنامه با اشیاء نوع مقداری خیلی بهتر است، چون آن‌ها دارای مشکل تبدیل‌های زیاد به شیء نوع  و برعکس نیستند.

با استفاده از Generic Collectionها، می‌توانید از تمام مزیت‌هایی که فکرش را بکنید برخوردار باشید، چون آن‌ها همانند آرایه‌ها type safe هستند و همانند ArrayList و دیگر مجموعه‌های غیر generic، در آن‌ها از کارایی و عملکرد بهتر و بیشتری برخوردار هستید و از هیچ‌کدام از مشکلاتی که گفته شد خبری نخواهد بود.

در بخش بعدی، چگونگی استفاده از یک مجموعه generic List را به شما نشان می‌دهیم.

ایجاد مجموعه‌های <Generic List<T در #C

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

اولین چیزی که باید به آن توجه کنید مجموعه generic به نام <List<int است، که به لیستی از نوع int اشاره می‌کند. اگر به سند این کلاس نگاه کنید، خواهید فهمید که در آنجا به شکل <List<T تعریف شده است، که T می‌تواند هر نوعی باشد.

برای مثال، اگر می‌خواهید لیست روی اشیاء نوع رشته یا customer کار کند، می‌توانید آن‌ها را به شکل <List<string یا <List<customer تعریف کنید و در این صورت آن‌ها فقط اشیاء رشته یا customer نگهداری می‌کنند. در مثال بالا، myInts فقط نوع int نگهداری می‌کند.

با استفاده از متد Add، می‌توانید هر تعداد شیء int که می‌خواهید، به مجموعه اضافه کنید. این مجموعه با آرایه‌ها فرق می‌کند، آرایه‌ها یک سایز ثابت دارند. کلاس <List<T دارای تعداد زیادی متد(مانند Contains، Remove و غیره) است که می‌توانید از آن‌ها استفاده کنید.

دو نوع حلقه for وجود دارند که باید آن‌ها را بشناسید. در نوع اول، شرایط حلقه از property به نام Count استفاده می‌کند که متعلق به لیست myInts است. این هم یکی دیگر از تفاوت‌های بین مجموعه‌ها (collectionها) و آرایه‌ها است.

چون آرایه از یک property به نام Length برای این منظور استفاده می‌کند. سپس، روش خواندن از یک موقعیت خاص در مجموعه <List<T (یعنی [myInts[i) دقیقه syntax مشابه با آنچه برای آرایه‌ها استفاده می‌کردید دارد.

دفعه بعد که خواستید از یک آرایه تک بعدی استفاده کنید، در عوض بهتر است از یک <List<T استفاده کنید. اما ابتدا اطمینان حاصل کنید که راه حل انتخابی شما با درجه و اندازه مشکلی که دارید همخوانی داشته باشد و از بهترین ابزار برای انجام کار استفاده کنید. معمولاً در NET Framework. در بسیاری از موارد، از []byte استفاده می‌شود.

کار با مجموعه‌های <Dictionary<Tkey, Tvalue

Dictionary یکی دیگر از generic collection‌های بسیار مفید است، که با مقادیر Key/value کار می‌کند. یک مجموعه غیر generic به نام Hashtable وجود دارد که همان کار Dictionary را انجام می‌دهد، به استثنای اینکه روی شیء نوع عملیات انجام می‌دهد.

به هر حال، همان‌طور که قبلاً در این جلسه توضیح دادیم، بهتر است از مجموعه‌های غیر Generic دوری کنید و در عوض از جایگزین‌های Generic استفاده کنید. سناریویی که برای این مثال استفاده می‌کنم این است که شما لیستی از مشتریانی که می‌خواهید با آن‌ها کار کنید را در اختیار دارید.

طبیعی است که از طریق CustomerID مشتریان، آن‌ها را پیگیری کنید. مثال Dictionary با نمونه‌ها یا instanceهایی از کلاس Customer کار می‌کند:

کلاس Customer در کد بالا دارای یک سازنده یا constructor است که باعث می‌شود مقداردهی اولیه آسان‌تر شود. همچنین حالت یا state آن از طریق propertyهای public مشخص شده است.

در این لحظه این شرایط چندان رضایت بخش نیست، اما اشکالی ندارد، چون تنها هدف این کلاس این که به شما کمک کند تا چگونگی استفاده از یک مجموعه Dictionary را بیاموزید.

مثال زیر با استفاده از اشیاء Customer به یک مجموعه Dictionary مقداردهی می‌کند و سپس به شما نشان می‌دهد که چگونه می‌توانید ورودی‌ها را از Dictionary استخراج کنید:

متغیر customers به شکل Dictionary<int>, Customer تعریف شده است.

با در نظر گرفتن اینکه تعریف رسمی Dictionary به صورت <Dictionary<Tkey, Tvalue است، معنای customers این است که دیکشنری‌ای وجود دارد که کلید آن از نوع int و مقدار آن از نوع Customer است.

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

من سه شیء Customer ایجاد کردم و به هر کدام یک ID و یک Name دادم. از ID به عنوان کلید و از کل شیء Customer به عنوان مقدار یا Value استفاده می‌کنم.

می‌توانید این شرایط را در فراخوانی انجام شده برای Add مشاهده کنید، که در آن custX.ID به عنوان کلید اضافه شده است (اولین پارامتر) و instance یا نمونه custX به عنوان مقدار یا value اضافه شده است (دومین پارامتر).

استخراج اطلاعات از یک Dictionary کمی متفاوت است.

برای این منظور، عملیات تکرار در دیکشنری مشتری با استفاده از یک حلقه for each انجام می‌شود و نوع بازگشتی آن <KeyValuePair<Tkey, Tvalue است، که در آن Tkey از نوع int  Tvalue از نوع Customer است، چون آن‌ها نوع‌هایی هستند که دیکشنری مشتریان با استفاده از آن‌ها تعریف شده است.

چون custKeyVal از نوع KeyValuePair<int>, Customer است، پس دارای propertyهای key و value می‌باشد که می‌توانید از طریق آن‌ها عملیات خواندن را انجام دهید.

در مثال ما، custKeyVal.key مقدار ID را برای instance یا نمونه Customer نگه می‌دارد و custKeyVal.value کل instance یا نمونه Customer را در خود نگه می‌دارد.

پارامترها در عبارت Console.WriteLine این وضعیت را با چاپ کردن ID (که از طریق property key به دست آمده است) و نام (که از طریق Property Name از نمونه Customer که این نمونه توسط property value‌ بازگردانده شده است، به دست آمده است) نمایش می‌دهد.

نوع Dictionary برای وضعیت‌هایی که لازم است اشیاء را از طریق چند شناساگر منحصر به فرد یا unique پیگیری کنید بسیار مفید است. برای راحتی کار شما، در لیست ۱-۲۰ نحوه عملکرد List و Dictionary را نمایش داده‌ایم.

لیست ۱-۲۰. مقدمه‌ای بر استفاده از Generic Collections با یک مثال از <List<T و <Dictionary<Tkey, Tvalue

هر موقع خواستید با استفاده از generic collectionها کد نویسی کنید، یک عبارت using System.Collections.Generic به فایل خود استفاده کنید (که در لیست ۱-۲۰ نیز مشاهده می‌کنید).

خلاصه

Generic Collectionها به خاطر داشتن قابلیت type safe (همانند آرایه‌ها) و قابلیت انعطاف‌پذیری مجموعه‌های غیر generic، بهترین ابزار ممکن را در اختیار شما قرار می‌دهند. Generic collectionهای بسیار زیادی وجود دارند که می‌توانید از بین آن‌ها انتخاب کنید (مانند Stack، Queue و SortedDictionary).

برای آشنایی با generic collectionهای دیگر، به System.Collections.Generic namespace مراجعه کنید.

منبع: C#-Station 

جلسه بعد                                                                جلسه قبل

 مطالب مرتبط

 مقدمه ای بر زبان برنامه نویسی #C و پلتفرم NET Framework.
7 دلیل منطقی برای آموختن #C
 طبقه بندی زبان های برنامه نویسی
به دست آوردن Exceptionها در #C و یافتن همه خطاها
 LINQ(زبان جستجوی یکپارچه)
برنامه نویسی شیءگرا چیست؟

از آخرین دوره های آموزشی و تخفیف ها مطلع شوید

با تکمیل فرم زیر ، از اخبار و اطلاعات به روز برنامه نویسی و تکنولوژی عقب نمانید

آخرین مطالب

آموزش جامع SQL Server (جلسه ۱۲)
آموزش جامع SQL Server (جلسه ۱۲)

دستور UPDATE در SQL Server برای تغییر داده‌های موجود در یک جدول، از دستور UPDATE به شکل زیر استفاده ...

آموزش جامع SQL Server (جلسه ۱۵)
آموزش جامع SQL Server (جلسه ۱۵)

دستور DROP TABLE در SQL Server گاهی، لازم است یک جدول که دیگر استفاده‌ای ندارد را حذف کنید. برای ...

آموزش جامع SQL Server (جلسه ۳۵: Window Functionها – بخش ۲)
آموزش جامع SQL Server (جلسه ۳۵: Window Functionها – بخش ۲)

بخش اول از آخرین مبحث دوره جامع آموزش SQL Server در جلسه قبلی بررسی شد. این مبحث که ...

آخرین دیدگاه ها

دیدگاه خود را درباره این پست بنویسید

فرم ارسال نظرات