این مقاله به بررسی جامع دلایلی میپردازد که چرا زبان برنامهنویسی سیشارپ (#C) به انتخاب اول بسیاری از توسعهدهندگان، به ویژه در اکوسیستم داتنت مایکروسافت (.NET ecosystem)، تبدیل شده است. دکتر میلان میلانویچ در این نوشتار، ضمن اشاره به سیر تحول این زبان از بدو پیدایش تاکنون، ویژگیها، قابلیتها و مزایای کلیدی آن را برای مخاطبان متخصص در حوزه توسعه نرمافزار با تاکید بر چارچوب داتنت، تشریح میکند.
چیستی سیشارپ
سیشارپ یک زبان برنامهنویسی مدرن، چند-پارادایمی (multi-paradigm programming language) است که توسط شرکت مایکروسافت توسعه داده شده است. این زبان که توسط اندرس هایلسبرگ (Anders Hejlsberg) و تیم او به عنوان بخشی از ابتکار داتنت (.NET initiative) طراحی گردیده، از ابتدا با رویکرد شیءگرا (object-oriented)، مؤلفهگرا (component-oriented) و با تاکید بر ایمنی نوع (type-safe) بنا نهاده شده است. نام این زبان، با اشارهای موسیقایی به علامت دیز (#) که در نتنویسی برای نیمپرده بالا بردن نت به کار میرود، به عنوان "یک گام فراتر" از زبانهای سی (C) و سیپلاسپلاس (C++) انتخاب شده و شکل ظاهری آن نیز تداعیگر "C++++" است.
در حالی که در نسخههای اولیه سیشارپ، نوشتن یک برنامه ساده "Hello World" نیازمند چندین خط کد با استفاده از فضاهای نام (namespaces)، کلاسها (classes) و تعریف متدها (method declarations) بود، این زبان به مرور زمان سادهتر شده است. با معرفی قابلیت "دستورات سطح بالا" (top-level statements) در سیشارپ 9، سادهترین برنامه در این زبان میتواند تنها در یک خط نوشته شود. سیشارپ در هسته خود، زبانی مدرن (با بهروزرسانی مداوم و افزودن ویژگیهای جدید)، بالغ (با سابقهای 25 ساله و تکامل چشمگیر در عین فعال بودن توسعه آن)، ایمن از نظر نوع (با جلوگیری از خطاهای نوع به واسطه سیستم نوع قوی خود)، چند-پارادایمی (پشتیبانی از برنامهنویسی شیءگرا به همراه سبکهای امری، اعلانی و تابعی)، مؤلفهگرا (با قابلیت توسعه مؤلفههای مستقل و قابل استفاده مجدد)، چندسکویی (cross-platform) (قابلیت اجرا بر روی ویندوز، لینوکس و مک)، همهکاره (مناسب برای توسعه طیف وسیعی از برنامهها از وب تا موبایل و دسکتاپ)، متنباز (open-source) (توسعه کامل آن به صورت باز در گیتهاب (GitHub) از نسخه 7) و خوانا (با طراحی مبتنی بر سهولت خواندن کد) است.
کامپایلر سیشارپ، کد زبان میانی (Intermediate Language - IL) تولید میکند که بر روی زمان اجرای زبان مشترک (Common Language Runtime - CLR) اجرا میشود. CLR بخشی از زمان اجرای داتنت (.NET runtime) است و با دیگر زبانها مانند افشارپ (F#) و ویژوال بیسیک (.NET) نیز به اشتراک گذاشته میشود. این رویکرد مزایایی نظیر مدیریت خودکار حافظه (automatic memory management)، ایمنی نوع و دسترسی به یک کتابخانه استاندارد جامع را فراهم میآورد.
ویژگیهای کلیدی زبان (The Language: Core Features)
آنچه در ابتدا توسعهدهندگان را به سیشارپ جذب کرد، تنها نحو آشنای آن برای برنامهنویسان جاوا (Java) و سیپلاسپلاس نبود، بلکه انتخابهای طراحی مناسب آن نیز نقش بسزایی داشت. در طول سالها، سیشارپ از یک زبان شیءگرای ساده به یک زبان بسیار غنیتر تبدیل شده است و از پارادایمهای برنامهنویسی متعددی با همان هسته اولیه پشتیبانی میکند.
مبانی شیءگرایی (Object-oriented foundations)
سیشارپ از ابتدا یک زبان برنامهنویسی شیءگرا بوده و بر پایه اصول کپسولهسازی (encapsulation)، وراثت (inheritance) و چندشکلی (polymorphism) بنا شده است. در این زبان، کلاسها (classes) برای مدلسازی موجودیتهای دنیای واقعی یا مفاهیم انتزاعی تعریف میشوند و وضعیت (فیلدها/خصوصیات) و رفتار (متدها) را در کنار هم قرار میدهند. اشیاء (objects) که نمونههایی از این کلاسها هستند، در زمان اجرا مورد استفاده قرار میگیرند. سیشارپ همچنین از رابطها (interfaces) (قراردادهای انتزاعی که کلاسها میتوانند آنها را پیادهسازی کنند) و کلاسهای انتزاعی (abstract classes) (کلاسهای پایه که برخی پیادهسازیها را ارائه میدهند اما قابل نمونهسازی نیستند) پشتیبانی میکند.
سیستم نوع (Type system)
سیستم نوع سیشارپ از یک سیستم نوع ایستا (static type system) نسبتاً ساده به یک سیستم بسیار پیچیدهتر با ویژگیهایی نظیر جنریکها (generics)، انواع nullable (nullable types)، تطبیق الگو (pattern matching) و رکوردها (records) تکامل یافته است. معرفی انواع مرجع nullable (nullable reference types) در سیشارپ 8.0 یک پیشرفت حیاتی بود که به جلوگیری از یکی از رایجترین خطاهای زمان اجرا در برنامهنویسی شیءگرا، یعنی خطای NullReferenceException، کمک شایانی کرد. سیستم نوع سیشارپ به شناسایی خطاها در زمان کامپایل کمک میکند و در عین حال امکان نوشتن کد رسا و واضح را فراهم میسازد.
جنریکها (Generics)
یکی از اولین و مهمترین افزودهها به سیشارپ، جنریکها (که در سیشارپ 2.0 معرفی شدند) بودند. جنریکها به شما اجازه میدهند کلاسها و متدها را با استفاده از مکاننگهدارها برای انواع تعریف کنید، که منجر به کد قابل استفاده مجدد و ایمن از نظر نوع میشود. برای مثال، برای ایجاد یک لیست از آیتمها، میتوانید از کلاس داخلی List<T> استفاده کنید که در آن T میتواند هر نوعی باشد. این بدان معناست که نیازی به ایجاد کلاسهای جداگانه مانند IntList و StringList نیست و در زمان کامپایل، بررسی نوع برای هر نوعی که استفاده میکنید انجام میشود.
عبارات لامبدا (Lambda expressions)
از حدود سال 2007، سیشارپ شروع به ادغام مفاهیم برنامهنویسی تابعی (functional programming) به منظور تکمیل جنبه شیءگرای خود کرد که این امر تحت تأثیر زبان افشارپ بود. معرفی عبارات لامبدا در سیشارپ 3.0 یک نقطه عطف مهم بود. یک عبارت لامبدا یک تابع بینام (anonymous function) است؛ قطعهای از کد که میتوانید به عنوان داده با آن رفتار کنید، آن را به اطراف منتقل کنید، در یک متغیر ذخیره کنید و بعداً آن را فراخوانی کنید. لامبداها نوعی "شکر نحوی" (syntactic sugar) تابعی را به ارمغان میآورند که انجام وظایف خاص را بسیار مختصر و رسا میکند.
لینک (LINQ - Language Integrated Query)
شاید مهمترین ویژگیای که باعث شد بسیاری از توسعهدهندگان عاشق سیشارپ شوند، لینک (Language Integrated Query) باشد. لینک که در سیشارپ 3.0 معرفی شد، مجموعهای از ویژگیهای زبانی و چارچوبی است که به شما امکان میدهد دادهها را به صورت اعلانی (declaratively) پرس و جو و دستکاری کنید. اگر تا به حال کوئریهای اسکیوال (SQL queries) نوشتهاید، لینک برایتان آشنا خواهد بود، با این تفاوت که میتوانید آن را بر روی انواع مختلف دادهها (مجموعهها در حافظه، جداول پایگاه داده، اسناد اکسامال و غیره) مستقیماً از داخل کد سیشارپ، با بررسی در زمان کامپایل و قابلیت تکمیل خودکار کد (intellisense) در محیط توسعه یکپارچه (IDE)، استفاده کنید.
برنامهنویسی ناهمگام (Asynchronous programming)
مدیریت عملیات ناهمگام (مانند عملیات ورودی/خروجی فایل، فراخوانیهای شبکه یا هر کار طولانیمدتی که نباید رشته اصلی (main thread) را مسدود کند) در سیشارپ چالشبرانگیز بود. پیش از این، برای مدیریت کارهای ناهمگام نیاز به استفاده از نخها (threads)، توابع بازگشتی (callbacks) یا رویدادها (events) بود که این رویکردهای پیچیده منجر به "جهنم توابع بازگشتی" (callback hell) میشد. سیشارپ با معرفی الگوی async/await در نسخه 5.0 این مشکل را حل کرد که از آن زمان به استاندارد طلایی برای برنامهنویسی ناهمگام در بسیاری از زبانها تبدیل شده است. async/await نه تنها عملکرد را بهبود میبخشد، بلکه یک روش شهودی برای پیادهسازی برنامهنویسی ناهمگام فراهم میکند و در عین حال سطح بهرهوری مشابه کد همگام را حفظ میکند. این الگو مستقیماً در زبان تعبیه شده است و یک چالش برنامهنویسی سنتی پیچیده را آسان میکند.
مدیریت حافظه (Memory management)
مدیریت کارآمد حافظه برای عملکرد و پایداری هر برنامهای حیاتی است. سیشارپ این جنبه مهم توسعه نرمافزار را از طریق سیستم مدیریت حافظه خودکار خود تسهیل میکند که توسط جمعآورنده زباله (garbage collector) در زمان اجرای زبان مشترک (CLR) انجام میشود. برخلاف زبانهایی مانند سی و سیپلاسپلاس که در آنها توسعهدهندگان باید به صورت دستی حافظه را تخصیص و آزاد کنند، سیشارپ این فرآیند را خودکار میکند. جمعآورنده زباله به طور دورهای حافظه برنامه را اسکن کرده و فضایی را که توسط اشیاء بلااستفاده یا بدون ارجاع اشغال شده است، بازپس میگیرد. این فرآیند خودکار به طور قابل توجهی خطر نشت حافظه (memory leaks) را که یک مشکل رایج در بسیاری از زبانها است، کاهش میدهد.