إصدارات C#: ما تخفيه الأرقام وكيف يعمل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

إصدارات C#: ما تخفيه الأرقام وكيف يعمل تحت الغطاء

\n\n

إذا كنت قد ألقيت نظرة على المناقشات في Stack Overflow، فمن المحتمل أنك رأيت سؤالًا جمع آلاف المشاهدات: "What are the correct version numbers for C#?". قد يبدو الأمر بسيطًا؟ تفتح الوثائق وتنتهي. لكن في الواقع، الأمور أكثر تعقيدًا. خاصة عندما تكتشف أن C# 7.0 صدر مع .NET Framework 4.7، بينما C# 8.0 صدر مع .NET Core 3.0. ولماذا C# 5.0 غير مرتبط بإصدار معين من .NET؟ مرحبًا بك في عالم تخدع فيه الأرقام.

\n\n

في هذه المقالة، لن نقوم فقط بسرد الإصدارات. سننظر تحت غطاء المترجم Roslyn، ونفهم كيف ترتبط أرقام الإصدارات بالمنصات، ونعرض بأمثلة كود فعلية الميزات التي ظهرت في كل إصدار. هيا بنا!

\n\n

لماذا سؤال إصدارات C# شائع جدًا؟

\n\n

الإجابة بسيطة: الخلط بين إصدارات لغة C# وإصدارات .NET. يعتقد العديد من المطورين أن C# 7.0 هو نفس .NET Framework 4.7. لكن هذا غير صحيح. لغة C# تعيش حياتها الخاصة، ومنصة .NET تعيش حياتها الخاصة. المترجم Roslyn (المعروف أيضًا باسم csc.exe) هو الجسر بينهما. يأخذ كود C# ويحوله إلى كود IL (Intermediate Language)، الذي يتم تنفيذه بعد ذلك بواسطة CLR (Common Language Runtime).

\n\n

هذه هي النقطة الأساسية: نفس إصدار المترجم يمكنه دعم إصدارات مختلفة من اللغة. على سبيل المثال، المترجم من Visual Studio 2019 يمكنه تجميع كود C# 7.0 و 7.1 و 7.2 و 7.3 و 8.0 — اعتمادًا على إعدادات المشروع. ولهذا السبب يوجد الكثير من الالتباس في Stack Overflow.

\n\n

تاريخ موجز لإصدارات C#

\n\n

دعنا نستعرض المعالم الرئيسية. لن أذكر جميع الإصدارات الـ 12 على التوالي — بل سأسلط الضوء على تلك التي غيرت اللعبة حقًا.

\n\n

C# 1.0 (2002) — البداية

\n

صدر الإصدار الأول من اللغة مع .NET Framework 1.0. كانت لغة مُدارة (managed) بتركيب نحوي مشابه لـ Java، ولكن بميزات فريدة مثل الخصائص (properties) و المفهرسات (indexers). لا LINQ، ولا async/await، ولا generics. بسيطة، موثوقة، مملة.

\n\n

C# 2.0 (2005) — Generics تغير كل شيء

\n

مع هذا الإصدار جاءت الأجناس (generics)، والطرق المجهولة، والمكررات (yield return)، والفئات الجزئية. كان هذا اختراقًا: بدلاً من كتابة ArrayList مع boxing/unboxing، يمكنك استخدام List<T>. ارتفع الأداء بشكل كبير.

\n\n
// C# 2.0 — generics\nList<int> numbers = new List<int> { 1, 2, 3 };\nnumbers.ForEach(n => Console.WriteLine(n * 2)); // طريقة مجهولة\n
\n\n

C# 3.0 (2007) — LINQ واللامبدا

\n

أكثر إصدار ثوري. LINQ (Language Integrated Query) غير نهج التعامل مع البيانات. تعابير اللامبدا، طرق التمديد، الأنواع المجهولة، مهيئات الكائنات — كل هذا ظهر هنا. لم يكن المترجم Roslyn قد وُلد بعد، لكن في C# 3.0 وُضعت أسس المستقبل.

\n\n
// C# 3.0 — LINQ واللامبدا\nvar evenNumbers = Enumerable.Range(1, 10)\n    .Where(x => x % 2 == 0)\n    .Select(x => x * x);\nConsole.WriteLine(string.Join(", ", evenNumbers)); // 4, 16, 36, 64, 100\n
\n\n

C# 5.0 (2012) — Async/await

\n

أصبحت البرمجة غير المتزامنة بسيطة كما لم يحدث من قبل. async و await ليسا مجرد سكر نحوي. المترجم يولد آلة حالة معقدة (state machine) تدير الخيوط. إذا كنت تكتب بلغة C# 5.0 أو أعلى، يمكنك نسيان الإدارة اليدوية لـ BeginInvoke و EndInvoke.

\n\n
// C# 5.0 — async/await\nasync Task<string> FetchDataAsync(string url)\n{\n    using (var client = new HttpClient())\n    {\n        return await client.GetStringAsync(url);\n    }\n}\n
\n\n

C# 6.0 (2015) — سكر للحياة اليومية

\n

لم يجلب هذا الإصدار نماذج جديدة، لكنه جعل الكود أنظف: تضمين السلاسل النصية (string interpolation)، والمهيئات للخصائص التلقائية، والمشغل الشرطي الفارغ (null-conditional operator) — كلها أشياء صغيرة تجعل الحياة أسهل.

المدونات

توصيات الكتب