کتاب C# 11 and .NET 7 – Modern Cross-Platform Development, 7th Edition
(سی شارپ 11 و دات نت 7، مبانی توسعه چند سکویی مدرن، ویرایش هفتم)،
راهنمایی قابل دسترس برای برنامه نویسان مبتدی تا متوسط برای مفاهیم،
کاربردهای دنیای واقعی و جدیدترین ویژگیهای C# 11 و NET 7. به همراه
تمرینات عملی با استفاده از Visual Studio 2022 و Visual Studio Code است.
جدیدترین نسخه این کتاب به طور گسترده ای بازنگری شده است تا تمامی
ویژگیهای جدید ارائه شده با سی شارپ 11 و دات نت 7 را در خود جای دهد.
دلایل شانه خالی کردن از آزمایش واحد!
1- نوشتن آزمایشات زمان زیادی را به خود اختصاص خواهند داد.
مهمترین دلیلی که برنامهنویسها به سبب آن از نوشتن آزمایشات واحد امتناع میکنند، همین موضوع است. اکثر افراد به آزمایش بهعنوان مرحله آخر توسعه فکر میکنند. اگر این چنین است، بله! نوشتن آزمایشهای واحد واقعا سخت و زمانگیر خواهند بود. به همین جهت برای جلوگیری از این مساله روش pay-as-you-go مطرح شده است (ماخذ: کتاب Pragmatic Unit Testing در سی شارپ). یعنی با اضافه شدن هر واحد کوچکی به سیستم، آزمایش واحد آنرا نیز تهیه کنید. به این صورت در طول توسعه سیستم با باگهای کمتری نیز برخورد خواهید داشت چون اجزای آنرا در این حین به تفصیل مورد بررسی قرار دادهاید. اثر این روش را در شکل زیر میتوانید ملاحظه نمائید (تصویری از همان کتاب ذکر شده)
نوشتن آزمایشات واحد زمانبر هستند اما توسعه پیوسته آنها با به تاخیر انداختن آزمایشات به انتهای پروژه، همانند تصویر فوق تاثیر بسیار قابل توجهی در بهره وری شما خواهند داشت.
بنابراین اگر عنوان میکنید که وقت ندارید آزمایش واحد بنویسید، به چند سؤال زیر پاسخ دهید:
الف) چه مقدار زمان را صرف دیباگ کردن کدهای خود یا دیگران میکنید؟
ب) چه میزان زمان را صرف بازنویسی کدی کردهاید که تصور میرفت درست کار میکند اما اکنون بسیار مشکل زا ظاهر شده است؟
ج) چه مقدار زمان را صرف این کردهاید که منشاء باگ گزارش شده در برنامه را کشف کنید؟
برای افرادی که آزمایشات واحد را در حین پروسه توسعه در نظر نمیگیرند، این مقادیر بالا است و با ازدیاد تعداد خطوط سورس کدها، این ارقام سیر صعودی خواهند داشت.
تصویری از کتاب xUnit Test Patterns ، که بیانگر کاهش زمان و هزینه کد نویسی در طول زمان با رعایت اصول آزمایشات واحد است
2- اجرای آزمایشات واحد زمان زیادی را تلف میکند.
نباید اینطور باشد. عموما اجرای هزاران آزمایش واحد، باید در کسری از ثانیه صورت گیرد. (برای اطلاعات بیشتر به قسمت حد و مرز یک آزمایش واحد در قسمت قبل مراجعه نمائید)
3- امکان تهیه آزمایشات واحد برای کدهای قدیمی ( legacy code ) من وجود ندارد
برای بسیاری از برنامه نویسها، تهیه آزمایش واحد برای کدهای قدیمی بسیار مشکل است زیرا شکستن آنها به واحدهای کوچکتر قابل آزمایش بسیار خطرناک و پرهزینه است و ممکن است سبب از کار افتادن سیستم آنها گردد. اینجا مشکل از آزمایش واحد نیست. مشکل از ضعف برنامه نویسی آن سیستم است. روش refactoring ، طراحی مجدد و نوشتن آزمایشات واحد، به تدریج سبب طراحی بهتر برنامه از دیدگاههای شیءگرایی شده و نگهداری سیستم را در طولانی مدت سادهتر میسازد. آزمایشات واحد این نوع سیستمها را از حالت فلج بودن خارج میسازد.
4- کار من نیست که کدهای نوشته شده را آزمایش کنم!
باید درنظر داشته باشید که این هم کار شما نیست که انبوهی از کدهای مشکل دار را به واحد بررسی کننده آن تحویل دهید! همچنین اگر تیم آزمایشات و کنترل کیفیت به این نتیجه برسد که عموما از کدهای شما کمتر میتوان باگ گرفت، این امر سبب معروفیت و تضمین شغلی شما خواهد شد.
همچنین این کار شما است که تضمین کنید واحد تهیه شده مقصود مورد نظر را ارائه میدهد و اینکار را با ارائه یک یا چندین آزمایش واحد میتوان اثبات کرد.
5- تنها قسمتی از سیستم به من واگذار شده است و من دقیقا نمیدانم که رفتار کلی آن چیست. بنابراین آن را نمیتوانم آزمایش کنم!
اگر واقعا نمیدانید که این کد قرار است چه کاری را انجام دهید به طور قطع الان زمان مناسبی برای کد نویسی آن نیست!
6- کد من کامپایل میشود!
باید دقت داشت که کامپایلر فقط syntax کدهای شما را بررسی کرده و خطاهای آنرا گوشزد میکند و نه نحوهی عملکرد آنرا.
7- من برای نوشتن آزمایشات حقوق نمیگیرم!
باید اذعان داشت که به شما جهت صرف تمام وقت یک روز خود برای دیباگ کردن یک خطا هم حقوق نمیدهند! شما برای تهیه یک کد قابل قبول و قابل اجرا حقوق میگیرید و آزمایش واحد نیز ابزاری است جهت نیل به این مقصود (همانند یک IDE و یا یک کامپایلر).
8- احساس گناه خواهم کرد اگر تیم فنی کنترل کیفیت و آزمایشات را از کار بی کار کنم!!
نگران نباشید، این اتفاق نخواهد افتاد! بحث ما در اینجا آزمایش کوچکترین اجزا و واحدهای یک سیستم است. موارد دیگری مانند functional testing, acceptance testing, performance & environmental testing, validation & verification, formal analysis توسط تیمهای کنترل کیفیت و آزمایشات هنوز باید بررسی شوند.
9- شرکت من اجازه اجرای آزمایشات واحد را بر روی سیستمهای در حال اجرا نمیدهد.
قرار هم نیست بدهد! چون دیگر نام آن آزمایش واحد نخواهد بود. این آزمایشات باید بر روی سیستم شما و توسط ابزار و امکانات شما صورت گیرد.
پ.ن.
در هشتمین دلیل ذکر شده، از acceptance testing نامبرده شده. تفاوت آن با unit testing به صورت زیر است:
آزمایش واحد:
توسط برنامه نویسها تعریف میشود
سبب اطمینان خاطر برنامه نویسها خواهد شد
واحدهای کوچک سیستم را مورد بررسی قرار میدهد
یک آزمایش سطح پائین ( low level ) به شمار میرود
بسیار سریع اجرا میشود
به صورت خودکار (100 درصد خودکار است) و با برنامه نویسی قابل کنترل است
اما در مقابل آزمایش پذیرش به صورت زیر است:
توسط مصرف کنندگان تعریف میشود
سبب اطمینان خاطر مصرف کنندگان میشود.
کل برنامه مورد آزمایش قرار میگیرد
یک آزمایش سطح بالا ( high level ) به شمار میرود
ممکن است طولانی باشد
عموما به صورت دستی یا توسط یک سری اسکریپت اجرا میشود
مثال : گزارش ماهیانه باید جمع صحیحی از تمام صفحات را در آخرین برگه گزارش به همراه داشته باشد
ادامه دارد...
فیلدهای استاتیکی که در سطح یک کلاس تعریف میشوند، برای نگهداری دادههایی به کار میروند که بین همهی اشیاء ساخته شدهی از آن کلاس مشترک هستند. لذا برای دستیابی به آنها، نیاز به ساختن شیءای از آن کلاس نبوده و از طریق خود کلاس در دسترس خواهند بود. اما نکتهای در مورد فیلدهای استاتیک وجود دارد و آن هم ترتیب مقدار دهی به آنها است که در این مجال قصد دارم به آن بپردازم.
در یک کلاس همانطور که میتوانیم متد استاتیک و یا پراپرتی استاتیک داشته باشیم، قادر هستیم فیلدهایی را نیز به صورت استاتیک تعریف نماییم. با نوشتن کلمهی کلیدی Static قبل از فیلد یک کلاس، آن فیلد تبدیل به فیلدی استاتیک شده و از این پس این فیلد، متعلق به اشیاء ساخته شدهی از کلاس نیست و تنها از طریق خود کلاس میتوان به آن دست یافت. اگر فیلد استاتیک به صورت خصوصی (private) تعریف شود، تنها اعضای داخلی آن کلاس میتوانند به آن دسترسی داشته باشند و آن را تغییر دهند؛ ولی اگر به صورت عمومیتری تعریف شود، هر نوعی که بتواند به آن دسترسی داشته باشد، میتواند مقدار آن را ببیند و تغییر دهد.
زمانیکه شما یک کلاس با فیلد استاتیک را تعریف میکنید باید مراقب ترتیب مقدار دهی آنها نیز باشید. به عنوان مثال کلاس زیر را در نظر بگیرید:
در نگاه اول شاید کد بالا بدون مشکل به نظر برسد؛ یعنی اگر بخواهیم از مقادیر این فیلدهای استاتیک استفاده کنیم، انتظار داریم فیلد MaxAttempts به مقدار 5، فیلد WarningAttempts به مقدار 2 و فیلد Threshold به تفاضل آنها یعنی 3 مقداردهی شده باشند. ولی اگر کد زیر را اجرا کنید خروجی متفاوتی را مشاهده خواهید کرد:
همانطور که در این خروجی مشاهده میکنید، مقدار فیلد Threshold به صفر مقداردهی شده است؛ در حالیکه ما انتظار عدد 2 را داشتیم.
دلیل این مقدار غیر منتظره را باید در سند مشخصات زبان سی شارپ ( C# Language Specification ) یافت. در سند مشخصات زبان سی شارپ، نحوهی استفادهی از این زبان و دستورات نحوی ( Syntax ) آن به صورت شفافی توضیح داده شدهاند. این سند بیان میکند هیچ فیلد استاتیکی هرگز نباید بدون مقدار باشد؛ یعنی اگر قبل از مقدار دهی یک فیلد استاتیک بخواهیم به مقدار آن دسترسی داشته باشیم، به مقدار اولیهی نوع آن فیلد، مقدار دهی خواهد شد. پس در مثال بالا چون فیلدهای MaxAttempts و WarningAttempts از نوع Integer هستند، مقدار پیشفرض صفر را خواهند گرفت. همچنین این سند بیان میکند که اگر در کلاسی چندین فیلد استاتیک تعریف شوند و آنها در چند سطر جداگانه مقداردهی شوند (همانند کاری که ما در مثال بالا انجام دادیم) بر طبق ترتیبی که عملیات مقداردهی به آنها انجام میگیرد، مقدار خواهند گرفت. یعنی وقتی که فیلد استاتیک Threshold مقدار دهی میشود، چون فیلدهای استاتیک MaxAttempts و WarningAttempts هنوز مقداردهی نشدهاند، مقدار صفر میگیرند. پس در نتیجهی فیلد Threshold هم مقدار صفر را میگیرد و چون ترتیب مقدار دهی نیز مهم است، مقدار آن با تغییر مقدار فیلدهای MaxAttempts و WarningAttempts تغیر نکرده و کماکان صفر باقی خواهد ماند و پس از آن در خطهای بعدی، فیلدهای MaxAttempts و WarningAttempts مقدار میگیرند.
پس برای رفع این مشکل باید ترتیب مقداردهی فیلدها را به گونهای تغییر داد که قبل از استفادهی از آنها، مقدارشان معلوم باشد.
اینبار خروجی زیر حاصل میشود:
مشکلی که این راه حل دارد این است که کد خوانایی نیست و قابلیت نگهداری خوبی هم ندارد. از آنجایی ما توسعه دهندگان عادت به تغییر کدهای دیگران را داریم، قابل پیش بینیاست که یک توسعه دهندهی دیگر، ترتیب نوشتن فیلدهای استاتیک را مثلا به قصد اینکه بخواهد آنها را به ترتیب حروف الفبا مرتب کند، تغییر دهد که اینکار منجر به یک باگ خواهد شد. یک راه حل بهتر این است که مقداردهی آنها را از تعریفاشان جدا کرده و عملیات مقداردهی به آنها را در یک سازندهی استاتیک قرار دهیم که در این صورت هم خروجی بالا را خواهیم داشت:
در یک کلاس همانطور که میتوانیم متد استاتیک و یا پراپرتی استاتیک داشته باشیم، قادر هستیم فیلدهایی را نیز به صورت استاتیک تعریف نماییم. با نوشتن کلمهی کلیدی Static قبل از فیلد یک کلاس، آن فیلد تبدیل به فیلدی استاتیک شده و از این پس این فیلد، متعلق به اشیاء ساخته شدهی از کلاس نیست و تنها از طریق خود کلاس میتوان به آن دست یافت. اگر فیلد استاتیک به صورت خصوصی (private) تعریف شود، تنها اعضای داخلی آن کلاس میتوانند به آن دسترسی داشته باشند و آن را تغییر دهند؛ ولی اگر به صورت عمومیتری تعریف شود، هر نوعی که بتواند به آن دسترسی داشته باشد، میتواند مقدار آن را ببیند و تغییر دهد.
زمانیکه شما یک کلاس با فیلد استاتیک را تعریف میکنید باید مراقب ترتیب مقدار دهی آنها نیز باشید. به عنوان مثال کلاس زیر را در نظر بگیرید:
class AttemptController { internal static int Threshold = MaxAttempts - WarningAttempts; internal static int MaxAttempts = 5; internal static int WarningAttempts = 2; }
Console.WriteLine("Maximum: {0}", AttemptController.MaxAttempts); Console.WriteLine("Warning: {0}", AttemptController.WarningAttempts); Console.WriteLine("Threshold: {0}", AttemptController.Threshold); /* OUTPUT Maximum: 5 Warning: 2 Threshold: 0 */
دلیل این مقدار غیر منتظره را باید در سند مشخصات زبان سی شارپ ( C# Language Specification ) یافت. در سند مشخصات زبان سی شارپ، نحوهی استفادهی از این زبان و دستورات نحوی ( Syntax ) آن به صورت شفافی توضیح داده شدهاند. این سند بیان میکند هیچ فیلد استاتیکی هرگز نباید بدون مقدار باشد؛ یعنی اگر قبل از مقدار دهی یک فیلد استاتیک بخواهیم به مقدار آن دسترسی داشته باشیم، به مقدار اولیهی نوع آن فیلد، مقدار دهی خواهد شد. پس در مثال بالا چون فیلدهای MaxAttempts و WarningAttempts از نوع Integer هستند، مقدار پیشفرض صفر را خواهند گرفت. همچنین این سند بیان میکند که اگر در کلاسی چندین فیلد استاتیک تعریف شوند و آنها در چند سطر جداگانه مقداردهی شوند (همانند کاری که ما در مثال بالا انجام دادیم) بر طبق ترتیبی که عملیات مقداردهی به آنها انجام میگیرد، مقدار خواهند گرفت. یعنی وقتی که فیلد استاتیک Threshold مقدار دهی میشود، چون فیلدهای استاتیک MaxAttempts و WarningAttempts هنوز مقداردهی نشدهاند، مقدار صفر میگیرند. پس در نتیجهی فیلد Threshold هم مقدار صفر را میگیرد و چون ترتیب مقدار دهی نیز مهم است، مقدار آن با تغییر مقدار فیلدهای MaxAttempts و WarningAttempts تغیر نکرده و کماکان صفر باقی خواهد ماند و پس از آن در خطهای بعدی، فیلدهای MaxAttempts و WarningAttempts مقدار میگیرند.
پس برای رفع این مشکل باید ترتیب مقداردهی فیلدها را به گونهای تغییر داد که قبل از استفادهی از آنها، مقدارشان معلوم باشد.
class AttemptController { internal static int MaxAttempts = 5; internal static int WarningAttempts = 2; internal static int Threshold = MaxAttempts - WarningAttempts; }
Maximum: 5 Warning: 2 Threshold: 3
مشکلی که این راه حل دارد این است که کد خوانایی نیست و قابلیت نگهداری خوبی هم ندارد. از آنجایی ما توسعه دهندگان عادت به تغییر کدهای دیگران را داریم، قابل پیش بینیاست که یک توسعه دهندهی دیگر، ترتیب نوشتن فیلدهای استاتیک را مثلا به قصد اینکه بخواهد آنها را به ترتیب حروف الفبا مرتب کند، تغییر دهد که اینکار منجر به یک باگ خواهد شد. یک راه حل بهتر این است که مقداردهی آنها را از تعریفاشان جدا کرده و عملیات مقداردهی به آنها را در یک سازندهی استاتیک قرار دهیم که در این صورت هم خروجی بالا را خواهیم داشت:
class AttemptController { internal static int MaxAttempts; internal static int WarningAttempts; internal static int Threshold; static AttemptController() { MaxAttempts = 5; WarningAttempts = 2; Threshold = MaxAttempts - WarningAttempts; } }
اشتراکها
سایتی برای یادگیری زبان سی شارپ
نحوه آموزش یک زبان برنامهنویسی و یا یک تکنولوژی معمولا در محبوبیت آن نقش مهمی دارند. معمولا تکنولوژیها و پلتفرمهایی محبوب میشوند که روش یادگیری آنها سادهتر و مستندتر باشد. سایت زیر برای یادگیری زبان C# روش جالبی را برگزیده است. در این سایت شما میتوانید زبان برنامهنویسی که قبلا با آن کار میکردهاید مانند VB6 یا C++ را انتخاب کنید. محتوی آموزشی این سایت بر اساس تجربه قبلی شما تغییر میکند تا با بازدهی بیشتری آموزش انجام شود.
سایتی در مورد پرسشها و پاسخهای طبقه بندی شده درباره
زبان برنامه نویسی سی
زبان برنامه نویسی ++C
زبان برنامه نویسی جاوا
تست نرم افزار
ساختارهای داده
SQL Sever
شبکه
سوالات مصاحبه ها
تستهای آنلاین
سوالات و پاسخهای طبقه بندی شده C# Programming
زبان برنامه نویسی سی
زبان برنامه نویسی ++C
زبان برنامه نویسی جاوا
تست نرم افزار
ساختارهای داده
SQL Sever
شبکه
سوالات مصاحبه ها
تستهای آنلاین
سوالات و پاسخهای طبقه بندی شده C# Programming
- Drag و Drop کردن در الگوی MVVM | محمد صاحب | www.dotnetdev.info
- اضافه کردن Copy to / Move to به منوی کلیک راست در ویندوز ویستا و ۷ | خدادادی طاقانکی | nodiran.com
- آموزش سی شارپ – قسمت اول | mr.khaliliazar | narbonsoft.com
- شبکه اجتماعی شیرپوینت 2010 ( قسمت اول) | تکتم قربانی | www.parnianportal.com
- نکته : کلمه it در عبارات جستجو حین استفاده از Entity Framework | mojtabasahraei | mojtabasahraei.blogfa.com
- Announcing The jQuery Standards Team | Addy Osmani | blog.jquery.com
- iText.NET - C# Examples | www.ujihara.jp
- VisualSVN Server 2.5.1 Released | www.visualsvn.com
- SubtitleTools 1.9 منتشر شد | subtitletools.codeplex.com
- Visual Studio 2010 SP1 به لیست آپدیتهای اختیاری ویندوز اضافه شد | blogs.msdn.com
- Visual Studio add-in for SQL Server Compact 3.5 and 4.0 | sqlcetoolbox.codeplex.com
- آمار فروش کتاب iText | lowagie.com
- آیا Delphi XE2 برای استفاده در محیط کاری آماده است؟ | www.itwriting.com
- خالق زبان Lisp درگذشت | rss.slashdot.org
- لیست امتحانات مرتبط با SQL Server 2012 | beyondrelational.com
اشتراکها
دوره آموزش سیشارپ مقدماتی
اشتراکها
50 سوال و جواب مصاحبه ی سی شارپ
اشتراکها