آموزش گام به گام #C (جلسه هفدهم: Enumها)
1398/01/21 12:28 , میلاد صاحب نظر

آموزش گام به گام #C (جلسه هفدهم: Enumها)

در برنامه‌نویسی گاهی کار کردن با مقادیر رشته‌ای و معنادار خیلی آسان‌تر از کار با مقادیر عددی است. enumها به ما کمک می‌کنند تا کدهای خود را خواناتر و کار با آن‌ها را ساده‌تر کنیم. با ما همراه باشید!

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

در این جلسه، نحوه استفاده از enumها را توضیح خواهیم داد. اهداف ما عبارت‌اند از:

  • درک اینکه enum چیست
  • کسب توانایی ایجاد نوع‌های جدید enum
  • آموختن نحوه استفاده از enumها
  • آشنایی با متدهای نوع Enum

تعریف Enumها

Enumها ثابت‌های نوعی هستند. آن‌ها عملا نوع‌های منحصر به فردی هستند که شما را قادر می‌سازند تا نام‌های سمبلیک به مقادیر عددی اختصاص دهید.

در #C به آن‌ها ثابت‌های نوعی گفته می‌شود، به این معنا که یک Enum از یک نوع را نمی‌توان به طور ضمنی به یک enum از نوع دیگر اختصاص داد، حتی اگر مقادیر اعضای درون آن‌ها یکسان باشند.

همچنین،‌ نمی‌توان نوع‌های عددی و enumها را به طور ضمنی با هم تعویض کرد. همه اختصاص‌ها بین نوع‌های مختلف enum و نوع‌های عددی به یک cast ضمنی نیاز دارند.

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

برای مثال، ترجیح می‌دهید با کدام نوع کد کار کنید: مجموعه‌ای از مقادیر به نام North، South، East و West یا مجموعه‌ای از اعداد ۰، ۱، ۲ و ۳ که به ترتیب به همان مقادیر جهت نگاشت شده‌اند؟ enumها از طریق نام‌های سمبلیک یا نمادی، کار با ثابت‌های نوعی را آسان‌تر می‌کنند.

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

در این جلسه و جلسه‌های بعدی خواهید دید که enumها هم با حرف اول کوچک (یعنی enum) و هم با حرف اول بزرگ (یعنی Enum) مورد استفاده قرار گرفته و به آن‌ها اشاره می‌شود.

ارتباط بین این دو کلیدواژه این است که نوع #C یعنی enum از نوع کتابخانه کلاس پایه (BCL) یعنی Enum ارث‌بری می‌کند.

برای تعریف enumهای جدید از نوع #C یعنی enum و برای پیاده‌سازی متدهای ثابت (Static) از enumها، از نوع BCL یعنی Enum استفاده می‌شود.

ایجاد یک Enum

کتابخانه کلاس NET Framework. شامل تعداد زیادی enum و مثال‌هایی از چگونگی استفاده از آن‌ها می‌باشد. برای مثال، هر دفعه که آیکنی روی MessageBox قرار می‌دهید، از MessageBoxIcon enum استفاده می‌کنید.

برای لیستی از enumهای موجود در کتابخانه کلاس NET Framework.، به سند فراهم شده برای کلاس Enum مراجعه کنید و روی لینک کلاس‌های مشتق (Derivede Classes) کلیک کنید.

هر موقع وضعیتی پیش آمد که لازم بود از مجموعه اعداد مرتبط در یک برنامه استفاده کنید، پس بهتر است آن اعداد را با enumها جایگزین کنید. این کار باعث افزایش خوانایی و امنیت نوع (type-safe) می‌شود.

لیست ۱-۱۷ شامل یک تعریف enum و کدی که از آن enum در یک عبارت switch استفاده می‌کند، می‌باشد. به جای استفاده از اعداد ۰، ۱ و ۲ در عبارت Switch، اگر از یک enum به نام volume استفاده کنید، کد شما خیلی معنادارتر خواهد شد.

لیست ۱-۱۷. ایجاد و استفاده از یک Enum: EnumSwitch.cs

لیست ۱-۱۷ شامل یک تعریف برای یک enum است. توجه کنید که در تعریف از کلیدواژه enum استفاده شده است، دارای یک شناساگر نوع (یعنی Volume) است و شامل یک لیست از مقادیر جدا شده توسط ویرگول می‌باشد که توسط آکولادها احاطه شده‌اند.

این enum از نوع Volume است و ما از آن برای تعریف متغیر myVolume در متد Main استفاده کرده‌ایم. چون یک enum در واقع یک نوع مقداری است، می‌توانیم مستقیما به آن یک مقدار (یعنی Volume.Medium) اضافه کنیم (درست مشابه نوع‌های ساده همچون int یا double).

وقتی متغیر myVolume تعریف و مقداردهی اولیه شد، در عبارت switch مورد استفاده قرار می‌گیرد. هر کدام از عبارات Case نماینده یک عضو منحصر به فرد از Volume enum هستند.

هر وقتی عضوی از Volume enum مورد استفاده قرار می‌گیرد، با استفاده از شناساگر “Volume” کاملا سنجیده می‌شود تا امنیت نوع (type safety) تضمین شود. برای مثال، اگر یک Meat enum در کد وجود داشت، آنگاه Meat.Medium مسلما معنی متفاوتی نسبت به Volume.Medium می‌داشت.

با وجود هر دو enumها در کد، تنها استفاده از شناساگر Medium بدون سنجش نوع، یک کار مبهم خواهد بود. با استفاده از شناساگر نوع، می‌توانید مطمئن شوید که چنین اشتباهاتی رخ ندهند.

استفاده از enumها

یک  enum معمولا به همان شکل که در لیست ۱-۱۷ گفته شد مشخص می‌شود، اما همچنین می‌توان با تغییر نوع پایه و مقادیر عضو آن، آن را سفارشی‌سازی کرد. به صورت پیش‌فرض، نوع یک enum همواره int است.

در هنگام تعریف enum، با مشخص کردن یک نوع خاص می‌توان این پیش‌فرض را تغییر داد. اگر قرار است از enum به صورت گسترده استفاده کنید و اگر از یک نوع کوچک‌تر استفاده شود، می‌توانید فرصتی برای صرفه‌جویی در حافظه ایجاد کنید، پس بهتر است از یک نوع متفاوت با نوع پیش‌فرض استفاده کنید.

دلیل دیگر تغییر پیش‌فرض این است که، ممکن است بخواهید نوع enum با یک نوع دیگر در برنامه شما تطابق داشته باشد و می‌خواهید به صورت گسترده (و بدون از بین رفتن دقت مقدار) بین این دو نوع Cast انجام دهید. نوع‌های قابل‌قبول enum عبارت‌اند از byte، sbyte، short، ushort، int، uint، long و ulong.

تغییر دیگری که می‌توانید در یک enum انجام دهید، مجموعه مقادیر عضو enum است. به صورت پیش‌فرض، اولین عضو یک enum مقدار صفر می‌گیرد. اگر این مقدار برای enum شما مناسب نیست، می‌توانید آن را به مقدار یک یا هر مقدار دیگری که بخواهید تبدیل کنید.

علاوه بر این، می‌توانید مقدار همه اعضای enum را به هر مقداری که برای نوع enum قابل‌قبول باشد، تغییر دهید. اعضایی از enum که مقداردهی نشده‌اند، به صورت پیش‌فرض دارای مقدار یکی بیشتر از مقدار عضو قبلی خود می‌باشند. لیست ۲-۱۷ چگونگی تغییر نوع و مقادیر اعضای یک enum را نشان می‌دهد.

لیست ۲-۱۷. تنظیم نوع Enum و مقداردهی اولیه اعضا: EnumBaseAndMembers.cs

Volume enum در لیست ۲-۱۷ چگونگی تغییر نوع و اعضای یک enum را نشان می‌دهد. نوع پایه آن با type>syntax>ه بعد از شناساگر enum (یعنی Volume) قرار گرفته است، به byte تغییر کرده است. این امر تضمین می‌کند که Volume enum فقط دارای اعضایی می‌باشد که دارای مقادیر قابل‌قبول برای نوع byte هستند.

مقدار اولین عضو Volume enum (یعنی low)، به ۱ تغییر کرده است. همان syntax یعنی <member> = <value> می‌تواند برای هر عضو از enum به کار رود. برای اعضای enum، فقط می‌توانید رفرنس‌های رو به جلو، رفرنس‌های حلقه‌ای (دایره‌ای) و رفرنس‌های تکراری ایجاد کنید و به همین سه نوع رفرنس محدود هستید.

مقادیر پیش‌فرض Volume enum عبارت‌اند از low=0، Medium=1 و High=2، چون مقدار اولین عضو یک enum به طور پیش‌فرض برابر با ۰ می‌باشد و بقیه اعضا نیز به طور پیش‌فرض به ترتیب مقادیر یکی بیشتر از عضو قبلی خواهند داشت.

به هر حال، مقدار عضو low در Volume enum از لیست ۲-۱۷ به ۱ تغییر داده شده‌ است، که یعنی Medium=2 و High=3 می‌باشد.

حقه‌ها و نکات enum

نوع‌های enum به طور ضمنی از نوع System.Enum در کتابخانه کلاس پایه (BCL) ارث‌بری می‌کنند. این همچنین بدان معنا است که می‌توانید از اعضای System.Enum برای انجام عمل روی نوع‌های enum استفاده کنید.

این بخش دقیقا همین کار را انجام می‌دهد، در این بخش چند نکته و حقه مفید برای کار با enumها در برنامه‌هایتان بیان خواهیم کرد.

کاری که معمولا با enumها انجام می‌شود، تبدیل بین enum و متغیری که هم نوع آن است، می‌باشد. برای مثال، اگر یک ورودی به فرم int یا یک فایل استریم از یک کاربر دریافت می‌کنید، آنگاه می‌توانید آن را به یک enum تبدیل یا Cast کنید و از آن به روش معناداری در برنامه خود استفاده کنید.

همچنین می‌توانید لیست کاملی از نام اعضای enum یا مقادیر enum بگیرید، که اگر برنامه شما منطقی داشته باشد که در آن لازم باشد هر عضو enum تکرار شود، این لیست مفید خواهد بود. لیست ۳-۱۷ چگونگی انجام تبدیلات بین enumها و نوع‌های پایه آن‌ها و چگونگی  استفاده از برخی اعضای نوع System.Enum را نشان می‌دهد.

لیست ۳-۱۷. تبدیلات enum و استفاده از نوع System.Enum: Enumtricks.cs

کد لیست ۳-۱۷ شامل سه متد به نام‌های GetEnumFromUser، ListEnumMembersByName و ListEnumMembersByValue می‌باشد. هر کدام از این متدها جنبه متفاوتی از استفاده System.Enum برای کاربر با enumها را نشان می‌دهند.

متد GetEnumFromUser چگونگی به دست آوردن ورودی int و ترجمه آن به یک نوع enum مناسب را نشان می‌دهد. تبدیل یک int به یک enum باعث می‌شود کد خواناتر و type-safe شود. کد زیر از لیست ۳-۱۷، بخشی را نشان می‌دهد که عمل تبدیل را انجام می‌دهد:

بعد از اینکه برنامه یک منو نمایش می‌دهد، از کاربر می‌خواهد تا یکی از اعداد ۱،۲ یا ۳ را انتخاب کند. وقتی کاربر انتخاب کرد و کلید enter را فشرد، کد مقدار را با عبارت Console.ReadLine می‌خواند، که این کد مقدار را به عنوان یک نوع String یا رشته بازمی‌گرداند.

چون فقط می‌توانید یک int را به نوع Volume enum تبدیل یا Cast کنید، پس ورودی کاربر باید از رشته به یک int تبدیل شود که این کار با متد Int32.Parse انجام می‌شود. تبدیل int به نوع Volume enum فقط یک عمل انجام Cast در طول فرآیند اختصاص مقدار است.

برای گرفتن هم‌زمان تمام اعضای یک enum، می‌توانید از متد GetNames از نوع System.Enum استفاده کنید، که یک آرایه با نوع رشته از نام‌ تمام اعضای یک enum بازمی‌گرداند. یک قطعه کد از متد ListEnumMembersByName در لیست ۳-۱۷ که این عمل را انجام می‌دهد در زیر آمده است:

چون GetNames یک آرایه از رشته‌ها بازمی‌گرداند، استفاده از آن در یک عبارت حلقه مانند foreach ساده و آسان است. چیزی که در کد بالا ممکن است کنجکاوی شما را برانگیزد، پارامتر دوم در فرمت رشته از متد WriteLine است.

با داشتن نوع enum و یک نماینده رشته از نام عضو، می‌توانید از متد Enum.Parse برای گرفتن مقدار درون آن عضو استفاده کنید.

چون نوع پایه Volume enum از نوع byte است، مقدار بازگشتی از Enum.Parse باید قبل از اختصاص داده شدن به یک byte تبدیل یا Cast شود و نماینده عددی از مقدار enum را مجبور به پدیدار شدن می‌کند.

اگر قسمت cast یا تبدیل byte را حذف کندی، خروجی برنامه، عضو Volume enum می‌باشد ، که آنگاه به یک نماینده رشته از نام عضو تبدیل می‌شود، اما قصد و هدف کد چنین خروجی‌ای نیست.

به جای اینکه نام‌های تمام اعضای یک enum را بگیرید، می‌توانید منطقی پیاده‌سازی کنید که همه مقادیر enum را به یک باره بگیرید. کد زیر، از متد ListEnumMembersByValue در لیست ۳-۱۷، چگونگی انجام این امر را نشان می‌دهد:

با توجه به نوع enum، متد GetValues از System.Enum آرایه‌ای از نوع پایه enum بازمی‌گرداند، که در این مثال، byte نوع پایه enum است. وقتی در طول این لیست عمل تکرار را انجام می‌دهید، هر عضو در کنسول چاپ می‌شود و مقدار و نامش را نمایش می‌دهد.

نام با استفاده از متد GetName از System.Enum به دست می‌آید، که این متد یک نوع و مقدار enum از عضوی که دارای نام مشابه با نام گرفته شده می‌باشد، می‌پذیرد.  

خلاصه

Enumها لیست‌هایی از ثابت‌های نوعی می‌باشند و دارای عضو هستند. این اعضا در واقع نام‌های سمبلیک هستند و به نوع‌هایی مانند نوع integral یا عددی اختصاص داده می‌شوند.

نوع‌های پایه enum و مقادیر اعضا قابل تغییر هستند. نوع System.Enum از کتابخانه کلاس NET Framework.، کلاس پایه از نوع‌های enum است و شامل متدهایی است که شما را قادر می‌سازند به روش‌های مختلف با enumها کار کنید (مثلا کار کردن با لیستی از نام‌ها یا مقادیر، تبدیل از مقدار به نام و تبدیل از نام به مقدار).

برای کسب اطلاعات بیشتر در مورد نوع System.Enum، به سند NET Framework SDK. مراجعه کنید.

منبع: 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 در جلسه قبلی بررسی شد. این مبحث که ...

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

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

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