pragma# و بقیه پیش پردانده ها در سی شارپ

کار اصلی دستورات پیش پردازنده در هر زبانی فراهم کردن اطلاعاتی برای کامپایر در مورد بخش هایی از کد است. در سی شارپ ۱۰ دستور پیش پردازنده وجود دارد. که به آنها نگاهی می اندازیم.

#define symbol

این دستور برای تعریف کردن یک نماد (symbol) استفاده می شود. نماد ها معمولا برای کامپایل شرطی بخش هایی از کد استفاده می شوند. به طور مثل نماد معروف DEBUG به ما کمک می کند با استفاده از دستورات پیش پردازنده شرطی، بخش هایی از کد را فقط در حالت DEBUG یا عدم وجود DEBUG کامپایل کنیم.

#if condition – #endif condition

 

اگر نماد DEBUG در هنگام کامپایل برنامه تعریف شده باشد خط مربوط به چاپ کردن پیغام روی کنسول، کامپایل خواهد شد. (دقت کنید که گفتم کامپایل نه اجرا در واقع اگر نماد DEBUG  تعریف نشده باشد در dll حاصل از کامپایل اثری از این خط نخواهد بود)

نکته: مثال مربوط به لاگ زدن فقط برای انتقال مطلب نوشته شده است. قطعا راههای مناسبتر و اصولی تری برای این نوع لاگ زدن وجود دارد که توضیح آن در موضوع این مطلب نیست.

#else – #elseif condition

همان طور که عنوان خود دستورات نشان می دهند این دستورات حالت else مربوط به بررسی شرط را ایجاد خواهند کرد مثلا وقتی نیاز است بر اساس وجود یا عدم وجود نماد DEBUG کارهای متفاوتی انجام دهیم. #elseif هم همینطور.

نکته مهم: نمادها هم از طریق فایل های کد قابل تعریف هستند و هم می توان آنها را در هنگام کامپایل به کامپایلر پاس داد. با استفاده از این امکان ویژوال استودیو نماد DEBUG را (در هنگامی که پروفایل build مربوط به DEBUG  را انتخاب می کنیم)، به پارامتر های قابل پاس داده شده به کامپایلر اضافه می کند. سویچ خط فرمانی مورد استفاده برای این کار به صورت زیر است.

نکته: علاوه بر این که می توان نماد ها را در فایل کد نیز تعریف کرد ویژوال استودیو رابط کاربری ای برای این کار ارائه می دهد که از همین نکته بالا برای عملی کردن آن استفاده می کند.

از مسیر زیر تب مربوط به properties یک پروژه را باز کنید:

Right click on project node in solution explorer / Properties (item)

تصویر ویژوال استودیو

تصویر ویژوال استودیو

اگر به تصویر بالا دقت کرده باشید متوجه می شوید در واقع هر پروفایل build ای مجموعه ای از properties را به هر پروژه اختصاص می دهد، که برای DEBUG تعریف نماد DEBUG را هم شامل می شود.

 #undef symbol

نمادی را که به صورت پارامتر به آن داده می شود را از بین می برد.

#warning message

این دستور پیش پردازنده پیغام warning ای را در خروجی کامپایل کامپایلر نمایش خواهد داد.

در تکه کد بالا اگر نماد DEBUG  تعریف شده باشد، کد به صورت عادی کامپایل می شود و کد مربوط به چاپ پیغام روی کنسول هم کامپایل خواهد شد. در صورتی که نماد DEBUG تعریف نشده باشد یک warning مبنی بر این که لاگ کار نخواهد کرد روی خروجی کامپایلر نمایش داده خواهد شد.

#error message

دقیقا مانند warning# قابل استفاده است با  این تفاوت که خطایی در خروجی کامپایلر نمایش داده خواهد شد و برنامه به صورت موفق کامپایل نخواهد شد.

#region name – #endregion

نیاز به توضیح ندارد!

مورد استفاده: از این دستورات برای بخش بندی کد استفاده می کنند خیلی از IDE ها از این دستورات برای نمایش نود های متفاوت کد به صورت دسته بندی شده استفاده می کنند.

#pragma

برای غیر فعال کردن warning بوجود آمده برای بخشی از کد استفاده می شود.

در تکه کد بالا اگر حتی نماد DEBUG تعریف نشده باشد هم warning ای در خروجی کامپایلر نمایش داده نخواهد شد. به این خاطر که ما تمامی warning های حاصل از آن بخش کد را غیر فعال کردیم.

نکته مهم: اگر از امکان  restore استفاده نکنیم برای آن بخشی از کد که بعد از disable هستند نیز تمامی warning ها غیر فعال خواهند شد.

مورد استفاده: از این دستور بیشتر در زمانی استفاده می شود که ما تغییری در کد داده ایم که منجر به ایجاد warning شده و میخو اهیم به کامپایلر بگوییم خودم حواسم هست! مثلا وقتی عمدا unreachable کد در کدهای ما ایجاد می شود و ما میخوام هیج warning ای نگیریم.

ConditionAttribute

این attribute در namespace این به آدرس System.Diagnostics قرار دارد.

از این attribute  می توانیم برای کامپایل کردن متدی بر اساس شرطی از نماد ها استفاده کنیم. به طور مثال

در مثال بالا ما به کامپایلر می گوییم که اگر نماد DEBUG وجود داشت متد را کامپایل کند. (البته این مثال خیلی معنا دار نیست چون باید به فکر زمانی هم باشیم که متد کامپایل نشده است و تمام استفاده های ما از این متد به خطا خواهند خورد)

دستورات پیش پردازنده مورد های استفاده عجیب و غریبی ندارند. شاید ماهها با این دستورات سر و کار نداشته باشیم. ولی خوشحال می شوم نمونه هایی از استفاده های خود را با من به اشتراک بگذارید.

اخلاق برنامه نویسی: تمرین

مثل تمامی مشاغل برنامه نویس ها هم به تمرین نیاز دارند.  حتی شاید خیلی بیشتر. مطالعه فنی خیلی به برنامه نویس بهتر شدن کمک میکند ولی در کل تمرین کردن از همه چیز بهتر است.

برای تمرین راههای متفاوتی وجود دارد. ولی من به شخصه سوالات برنامه نویسی را ترجیح می دهم. سوالاتی که خیلی وقتا ها آدم را با مبانی و اصول اولیه برنامه نویسی آشتی می دهند!

همیشه یادگیری اصول و پایه زبان هایی که به صورت روزمره با آنها کار می کنیم در نوشتن کد های بهتر و کاراتر تاثیر مثبتی می گذارد.

برای تمرین یکی از بهترین راهها استفاده از online judge ها برای حل سوالات برنامه نویسی است.

چون سی شارپ یکی از زبان های مورد علاقه من هست و به طور کلی خیلی زیاد با آن در ارتباط هستم، همیشه دوست داشتم سیستمی وجود داشته باشد که بتوان سوالات را با سی شارپ حل کرد. چند سیستمی که خیلی قوی هم هستند زبان های جاوا و ++C را به طور عمده پشتیبانی می کنند. (UVA و …)

با یک مقدار جستجو دو تا سیستم خوب پیدا کردم که سی شارپ را هم به رسمیت میشناسند! (البته پیاده سازی mono را)

  • project euler   (زبان برنامه نویسی مهم نیست / بیشتر سوالات ریاضی وار)
    این وبسایت حدود ۵۰۰ سوال که بیشتر مبنای نظری ریاضیاتی دارند را مطرح کرده که به صورت فعال توسط برنامه نویسان مختلف در حال بررسی هستند. بر خلاف سیستم های استاندارد سوالات برنامه نویسی این سایت هیچ امکانی برای آپلود کد و اجرای کد سمت سرور ندارد. جواب سوالات هیشه یک عدد است که برنامه شما باید آن عدد را درست حساب کند.
  • spoj (زبان های زیادی را پشتیبانی می کند / سی شارپ هم پشتیبانی می کند / سوالات به سبک سوالات کلاسیک برنامه نویسی است)
    این موتور که تازه با آن آشنا شده ام سیستم جالبی است که خیلی کاربران فعالی هم دارد. زبان برنامه نویسی سی شارپ را هم پشتیبانی می کند که برای من امکان خیلی خوبی است! سوالات فراوان و بعضی وقت ها (اگر با زبانی مثل سی شارپ یا جاوا کار کنید) مشکلی دارد. با این که به تازگی آشنا شده ام با این سیستم به نظرم وقت گذاشتن و تمرین کردن سوالات این سایت گزینه مناسبی باشد.

کلا کد نوشتن خیلی به یک برنامه نویس بهتر شدن کمک میکند!

تمرین کنیم! (البته من هم تنبلم!)

مطلب جالبی درباره string در دات نت!

به تکه کد زیر یک نگاهی بکنید:

دو تا متغیر از نوع رشته در سی شارت درست کرده ایم. سپس با متد ReferenceEquals مربوط به کلاس object بررسی کرده ایم که آیا reference این دو متغیر یکسان هستند یا نه. همون طور که می دانید string از انواع Reference هستش، باید دو متغیری که درست کرده ایم با دو رفرنس متفاوت باشند. در واقع دو object جداگانه برای هر کدام ایجاد شده باشد. ولی این طور نیست! و نتیجه متد ReferenceEquals نشون میده که این دو متغیر از نظر reference یکسان هستند! یک مقداری بی معنی به نظر میرسه. ولی دلیل این اتفاق این است که دات نت برای درست کردن مقادیر از نوع string از یک مکانیزم به نام pool استفاده می کنه. وقتی شما یک مقدار رشته ای رو ایجاد میکنید اگر این مقدار در pool مورد نظر باشه اشاره گری به اون برگردونده میشه، این کار رو نمیکنه که یک شی جدید برای اون بسازه. جالبه! یکی از دلایلی که string ها immutable هستند هم همینه! جالبه…

ایجاد پرسش های linq به صورت پویا

مقدمه

حتما تا به حال به این مسئله بر خورده اید که در برنامه ی نیاز به فیلتر کردن یک سری اطلاعات با استفاده از پارامتر های ورودی کاربر وجود داشته باشد. به طور مثال نیاز به جستجوی کالاها در پایگاه داده بر اساس قیمت یا اندازه یا سال ساخت یا دیگر خصوصیات آن، باشد. و بعضی از این پارامترها به صورت اختیاری ظاهر خواهند شد. در اینگونه مواقع یکی از راههایی که به ذهن می‌رسد این است که کد پرسش sql مربوط به جستجو را به صورت پویا و با در نظر گرفتن ورودی های کاربر درست کنیم. این راهی است که خیلی از ما معمولا از آن استفاده می‌کردیم. ولی وقتی از تکنولوژی ای مانند linq to sql برای ارتباط با پایگاه داده استفاده می‌کنیم و نیاز داریم اطلاعات بازگردانده شده از طریق پرسش به صورت تعریف نوع شده باشند، این روش چندان جالب به نظر نمی‌رسد. به طور مثال وقتی قصد داریم روی جدول products در یک datacontext یک پرس Linq اجرا کنیم، باید با توجه به ورودی‌های کاربر آن پرسش linq را تولید کنیم. (به زبان کاملا ساده!)

به طور مثال می‌خواهیم پرسشی به صورت زیر را در نهایت روی context مورد نظر خود اجرا نماییم.

ادامه در فایل پی دی اف ….

معرفی کلاس Lazy در دات نت ۴

 

کلاس Lazy

با سلام

احتمالا تا به حال این سوال در ذهن شما مطرح شده که آیا امکان دارد که ایجاد یک متغیر را تا زمانی که آن متغیر مورد استفاده قرار گیرد به تعویق اندازیم یا نه. این وضعیت در مواقعی نمود بیشتری پیدا میکند که متغیر یا فعالیت مرتبط با آن به نسبت سنگین باشد. در .net4 این امکان بوسیله کلاسی به نام lazy در فضای نام System ایجاد شده است. متغیری که با استفاده از کلاس مذکور اعلان و تعریف می شود هنگامی بوجود می آید (منظور از بوجود آمدن در این جا این است که به طور واقعی و به اندازه مورد نیاز فضای حافظه دریافت کند یا فعالیت مورد نظر همراه آن اجرا شود) که دسترسی که مقدار آن متغیر انجام شود (lazy<T>.Value) یا متد Lazy<T>.ToString از متغیر مربوطه فراخوانی شود.

مثال زیر نحوه استفاده از این کلاس را مشخص می نماید. برای درک بهتر این مثال نیاز است که مفاهیمی همچون delegate و anonymous function آشنایی داشته باشید.
تابع PrintSystemInfo در این برنامه عمل استفاده از متغیر را به صورت ساده انجام می دهد.تکه کد بالا نحوه ایجاد کردن یک شی از کلاس Lazy را نمایش میدهد. کلاس Lazy به صورتی است که باید نوع متغیری را که نیاز به ایجاد دیر هنگام داریم را مشخص کنیم. در اینجا نوع ما لیستی از رشته ها است (List<string> processes) تابع ایجاد کننده ای که در اینجا استفاده کرده ایم، تابعی را (delegate مربوط به آنرا) که متغیر مورد نظر ما را تولید می کند به عنوان پارامتر دریافت می کند. این تابع باید در نهایت متغیر مورد نظر ما را به عنوان خروجی بازگرداند.

 

این تابع پارامتر ورودی هم نوع با متغیر تعریف شده ما با استفاده از کلاس Lazy دریافت می کند (Lazy<List<string>> processNames). عمل دسترسی به مقدار متغیر و در نتیجه ایجاد آن متغیر به صورت زیر انجام می گیرد.
کد برنامه مثال را از اینجا دانلود کنید…در واقع در اولین دسترسی به این متغیر با استفاده از روش بالا متد مربوط به ایجاد آن متغیر اجرا شده و متغیر به صورت واقعی ایجاد می شود.

موفق و پیروز باشید…

کلاس هایی ساده برای ایجاد و استفاده از مجموعه ها در net.

برای استفاده از امکان ایجاد مجموعه ها و استفاده از عملگر های مجموعه ای در حال حاضر چند کتابخانه وجود دارد. که با استفاده از امکانات موجود در net. به این کار میپردازند. لیست این کتابخانه و مقالات رو در ادامه خواهید دید.

نام مقاله یا کتابخانه لینک دسترسی
Add Support for “Set”Collections to .NET http://www.codeproject.com/KB/recipes/sets.aspx
کلاس HashSet در net4.

http://msdn.microsoft.com/en-us/library/bb495294.asp

این فکر ۳ سال در ذهنم بود که یک کلاس ساده برای استفاده از مجموعه ها بنویسم! کلاس های موجود در لیست بالا کلاس های کارآمد و مناسبی برای فعالیت های مجموعه ای در .net هستند. ولی کلاس نوشته شده توسط من بیشتر جنبه ی آموزشی دارد. و برای فهم عملکرد آن نیازی به دانش چندانی از .net نیست.

… ادامه در فایل  pdf ….

فایل حاوی مستندات و سورس برنامه و کتابخانه در لینک زیر قابل دسترسی است…

صفحه ی پروژه در codeplex