Programming Before .NET

قبل سنة 2002، مايكروسوفت عملت لغات زي Delphi و VB و Visual Cpp، بس فكرت إنها تعمل الـ .NET بسبب مشكلتين أساسيتين:
- مقدرش أعمل برنامج يشتغل على كل الـ platforms المختلفة (يعني Can’t create Cross-platform app).
- مقدرش أشتغل في نفس الـ project بأكتر من لغة (يعني No cross language).
عشان نوضح ده أكتر، لازم نقول الـ Life cycle قبل الـ .NET كان عامل إزاي:
- لو عايز أعمل برنامج، بكتب الـ code بتاعي.
- الـ compiler بياخد الـ code ده ويحوله لـ Native code اللي هو أصفار ووحايد (0,1)، وده بنسميه platform dependent.
- يعني بيعتمد على الـ platform اللي بيترجم عليه البرنامج، وده لأن الـ structure بتاع كل platform مختلفة عن التانية.
Programming After .NET (2002)
الـ .NET Framework: عبارة عن Big Container for software technologies زي الـ Web اللي هو (ASP)، والـ Mobile اللي هو (Xamarin)، والـ Desktop اللي هو (WPF). وهو بيعتبر إطار عمل. (مع مراعاة إن Xamarin كان في الأصل إطار عمل مستقل وبعدين أصبح جزء من الـ .NET Ecosystem ككل مع .NET 5 وما بعدها).
الـ Framework ده بيتكون من حاجتين أساسيتين:
-
الـ Base Class Library (BCL): دي عبارة عن Base Library وبنقول عليها Standard، جواها (Classes) و (Methods) وحاجات جاهزة عشان نستخدمها على طول. مثلاً:
- الـ class اللي اسمه
Stringاللي بيتعامل مع النصوص موجود جوه مكتبةSystem، والمكتبة دي ضمن مجموعة كبيرة من الـ Standard Libraries اللي بتوفرها الـ BCL. - فيه مكتبات تانية عشان تتعامل مع الملفات، الشبكات، الـ DB، وغيرها كتير.
- الـ BCL بيعتبر حجر الأساس اللي بتعتمد عليه الـ Technologies جوه الـ .NET.
- الـ class اللي اسمه
-
الـ CLR (Common language runtime): وده يعتبر قلب الـ .NET Framework، وهو المسؤول إنه يشغل أي أبلكيشنز .NET. وبيتكون من 3 حاجات: 3. لغات الـ DotNet وأشهرهم C# و VB.NET و F#، واللغات دي بتتحول لـ code وسيط اسمه IL. 4. الـ compiler بتاع كل لغة، يعني مثلاً بتاع الـ C# اسمه Roslyn، وده اللي بيحولها لـ IL. 5. الـ Runtime Components: ودي المسؤولة عن إدارة الذاكرة (Garbage Collection)، والـ Exception Handling، وتأمين Virtual Environment عشان الـ code يشتغل، وغير كده حاجات كتير عشان الـ application يشتغل كويس.

.NET Code Compilation Steps

عشان نتخيل الخطوات بشكل أوضح، دي رسمة بتوضح الـ Flow:
graph TD A[C# Code] -->|Roslyn Compiler| B[IL Code + Metadata] B -->|Saved as| C[Assembly DLL/EXE] C -->|Platform Independent| D[CLR Runtime] D -->|JIT Compiler| E[Native Machine Code 0,1] E --> F[Executed on OS]
- إنت بتكتب الـ code بلغة C#، وبعد كده Roslyn (الـ compiler بتاع C#) بيعمل Compile للـ code بتاعك.
- بعد الـ Compile الـ code بيتحول لـ IL (أو CIL أو MSIL، يعني Common Intermediate Language) وبيتحط جوه فايل اسمه Assembly (سواء كان امتداده DLL أو EXE). الفايل ده عبارة عن IL + Metadata، ومالوش أي علاقة بـ “الاسمبلي” العادي (اللي هو اللغة منخفضة المستوى)، ده تشابه أسامي بس. يعني الـ “Assembly” بتاع الـ .NET هو حزمة IL و Metadata، مش كود اسمبلي بتاع المعالج.
- الفايل ده بيكون Platform independent. يعني الـ IL اللي جوه الـ Assembly ده ملف مستقل عن أي platform سواء (Windows, Linux, Mac). نفس الفايل الـ IL يشتغل على أي منصة فيها CLR مناسب من غير ما تعيد عملية الـ Compile. بس الفايل ده مش هيأكل عيش، عشان الكمبيوتر مبيفهمش غير machine code.
- هنا بيدخل عملية الـ runtime. الـ CLR بتستخدم الـ JIT Compiler (Just In Time Compiler) عشان تاخد الـ IL وتحوله لـ code نوعه Native (اللي بيفهمه المعالج مباشرة).
Danger
لسه المشكلة بتاعت الـ cross platform ماتحلتش في الـ .NET Framework، لأن كل platform زي (Linux, Mac, win) المفروض يبقى ليهم الـ CLR الخاص بيهم وليهم الـ JIT compiler الخاص بيهم عشان يعمل المرحلة الأخيرة دي على جهازه والبرامج تشتغل. فمايكروسوفت المفروض تعمل لكل platform حاجة اسمها SDK خاص بيها فيه الـ Compiler، بس ده محصلش.
SDK (Software Development Kit)
هو مجموعة الأدوات والمكتبات اللي بتسهل الـ Development وبيبقى فيه حاجات كتير:
- Compiler
- Libraries
- Tools (Like CLI)
- Templates
- Runtime (.NET Core or .NET Framework)
Runtime vs Compilation
- الـ Compilation: هي عملية تحويل الـ code لـ IL وبنستخدم فيها compiler زي Roslyn وده اللي بيظهر فيه الـ Compilation errors.
- الـ Runtime: عملية تحويل الـ IL إلى Native (exe) ودي بنستخدم فيها الـ JIT وبيظهر فيه الـ Runtime error.
Life Cycle Differences (Before and After)
الفرق في الـ Life cycle قبل وبعد هو الـ JIT Compiler، وده هيعملي overhead in runtime وهيبطأ الـ Runtime شوية.
عشان يحلوا المشاكل دي:
- الـ JIT خلوه 64bit وده أسرع.
- الـ Jitting بيحصل مرة واحدة بس لما بعمل call function، وطالما أنا مقفلتش البرنامج هيفضل زي ما هو ومش هيحتاج يعمل تاني.
Note
عندنا وقتين في الـ Life cycle:
- وهي عملية الـ compiler لـ IL.
- والـ JIT compiler وده في الـ .net Framework القديم.
ده مش حل كامل للأسف، فإحنا كده حلينا المشكلة التانية وهي إني أكتب بأكتر من لغة برمجة، بس المشكلة الأولى لسه ماتحلتش.
.NET Core (New Era)
- اتعمل في 2014 واتغلب على المشاكل السابقة وظهر للناس في 2016.
- قبلها كان فيه team من الـ developers شغالين على حاجة اسمها Mono Project/framework وهو عبارة عن حل لمشكلة الـ Cross platform إني أكتب الـ code على أكتر من حاجة ويشتغل عليهم. دي كانت حاجة مش رسمية فمكنش فيه support وكان بيبقى دايماً متأخر version عن الـ DotNet Framework.
- عشان كده عملوا الـ .NET Core.

- الـ Component Based: عندنا حاجة اسمها package manager أقدر أنزل منها package/library اللي أنا محتاجها في الـ project بتاعي عن طريق الـ NPM (Nuget.org Package Manager).
Notes
- الـ Roslyn Compiler: الـ compiler اللي اسمه
Roslynمكنش موجود سنة 2002 واول ما طلع كان مع .NET Framework الأول. وقبلها كان بيستخدم مترجم تقليدي (csc.exe).Roslynظهر فالاخر كـ open-source compiler في عام 2014 تقريباً. - الـ NPM vs NuGet: الـ Package Manager الخاص ببيئة دوت نت يُسمى NuGet (ويتم الوصول إليه عبر nuget.org). أما الـ NPM فهو اختصار لـ Node Package Manager الخاص ببيئة JavaScript/Node.js.
- الـ JIT Overhead: عشان نخفف (Overhead) اللي بيسببه الـ JIT Compiler، قدمت مايكروسوفت مؤخرا محرك JIT محسّن جداً يُعرف باسم RyuJIT (وهو الـ 64-bit compiler)، واللي ساعد في تسريع عملية تحويل الـ IL إلى Native Code بشكل ملحوظ.