المحاضرة الكاملة في C#

List — Class — Object — Encapsulation — Inheritance

مادة مرجعية منظّمة · أمثلة عملية · تمارين مع حلول


جدول المحتويات

# الموضوع
1 List — القوائم الديناميكية
2 Class — التصنيف كقالب
3 Object — الكائن
4 Encapsulation — التغليف
5 Inheritance — الوراثة
التمارين العملية

مقدمة سريعة

في هذه المحاضرة نربط بين تخزين البيانات (List) وبين نمذجة العالم الحقيقي (Class / Object)، ثم نضيف طبقتين مهمتين في البرمجة كائنية التوجه: إخفاء التفاصيل (Encapsulation) وإعادة استخدام السلوك (Inheritance). بعد الفهم النظري ننتقل إلى تمارين تغطي كل فكرة على حدة.


1) List — القوائم الديناميكية

التعريف: List<T> قائمة ديناميكية تحفظ عناصرًا من نوع واحد (T)، ويمكن أن يتغير حجمها أثناء التشغيل (عكس المصفوفة الثابتة غالبًا).

ما الذي تتيحه عادةً؟

أهم الأعضاء (Members) الشائعة

العضو الدور
Add إضافة عنصر في نهاية القائمة
Remove حذف أول تطابق للقيمة
RemoveAt حذف العنصر عند فهرس معيّن
Contains يعيد true إن وُجد العنصر
Count عدد العناصر
Sort ترتيب القائمة (للأنواع القابلة للمقارنة)

مثال تمهيدي

List<int> numbers = new List<int>(); numbers.Add(10); numbers.Add(20); numbers.Add(30); Console.WriteLine(numbers.Count); // 3

2) Class — التصنيف كقالب

التعريف: الـ class هو قالب (Template) يصف الحقول والـ السلوك (الدوال) لكيان في البرنامج. لا يُنشئ ذاكرة للكائنات بحد ذاته حتى تستخدم new.

class Book { public string Title; public string Author; }

3) Object — الكائن

التعريف: الـ object هو نسخة حية من الـ class في الذاكرة؛ لكل نسخة قيمها الخاصة للحقول.

Book b1 = new Book(); b1.Title = "C# Basics"; b1.Author = "Abdullah";

4) Encapsulation — التغليف

الفكرة: إخفاء تفاصيل التخزين أو القواعد الحساسة داخل الـ class، وتقديم واجهة آمنة (دوال مثل SetBalance / GetBalance) بدل السماح بتعديل مباشر غير مضبوط.

لماذا؟ لأنك تضمن مثلًا أن الرصيد لا يصبح سالبًا إلا إذا سمحت أنت بذلك داخل الدالة.

class BankAccount { private int balance; public void SetBalance(int amount) { if (amount >= 0) { balance = amount; } } public int GetBalance() { return balance; } }

5) Inheritance — الوراثة

التعريف: صنف فرعي يرث أعضاء الصنف الأساسي، ثم يضيف ما يميّزه. يربط هذا بين «إنسان عام» و«طالب» أو «معلّم» في المثال التالي.

class Person { public string Name; } class Student : Person { public int Grade; }

التمارين العملية

أدناه نص كل تمرين ثم حل مقترح يمكن إخفاؤه/إظهاره. جرّب الحل بنفسك أولًا.


التمرين 1 — علامات في List + طباعة + متوسط حسابي

المطلوب: برنامج يطلب من المستخدم إدخال 5 علامات، يخزنها في List<int>، يطبعها، ثم يحسب المتوسط الحسابي.

عرض الحل
using System; using System.Collections.Generic; class Program { static void Main() { List<int> marks = new List<int>(); for (int i = 0; i < 5; i++) { Console.Write("أدخل علامة: "); int m = int.Parse(Console.ReadLine()); marks.Add(m); } Console.WriteLine("العلامات:"); for (int i = 0; i < marks.Count; i++) { Console.WriteLine(marks[i]); } int sum = 0; for (int i = 0; i < marks.Count; i++) { sum += marks[i]; } double avg = sum / (double)marks.Count; Console.WriteLine("المتوسط الحسابي = " + avg); } }

التمرين 2 — صنف User + ثلاثة كائنات

المطلوب: عرّف class User يحتوي Name و Age، ثم أنشئ ثلاثة كائنات واطبع بياناتهم.

عرض الحل
using System; class User { public string Name; public int Age; } class Program { static void Main() { User u1 = new User(); u1.Name = "Ahmad"; u1.Age = 20; User u2 = new User(); u2.Name = "Sara"; u2.Age = 22; User u3 = new User(); u3.Name = "Omar"; u3.Age = 19; Console.WriteLine(u1.Name + " - " + u1.Age); Console.WriteLine(u2.Name + " - " + u2.Age); Console.WriteLine(u3.Name + " - " + u3.Age); } }

التمرين 3 — Person + وراثة Teacher و Student

المطلوب:

ثم أنشئ معلّمين اثنين وطالبين اثنين واطبع بياناتهم.

عرض الحل
using System; class Person { public string Name; public int Age; } class Teacher : Person { public string Subject; } class Student : Person { public int Grade; } class Program { static void Main() { Teacher t1 = new Teacher(); t1.Name = "Ali"; t1.Age = 40; t1.Subject = "Math"; Teacher t2 = new Teacher(); t2.Name = "Mona"; t2.Age = 35; t2.Subject = "English"; Student s1 = new Student(); s1.Name = "Hadi"; s1.Age = 16; s1.Grade = 90; Student s2 = new Student(); s2.Name = "Lama"; s2.Age = 17; s2.Grade = 95; Console.WriteLine(t1.Name + " - " + t1.Age + " - " + t1.Subject); Console.WriteLine(t2.Name + " - " + t2.Age + " - " + t2.Subject); Console.WriteLine(s1.Name + " - " + s1.Age + " - " + s1.Grade); Console.WriteLine(s2.Name + " - " + s2.Age + " - " + s2.Grade); } }

التمرين 4 — إدخال غير منتهٍ حتى exit

المطلوب: برنامج يضيف أرقامًا إلى List<int> في حلقة لا نهائية تقريبًا (while (true))، ويتوقف عند كتابة exit ثم يطبع كل الأرقام.

عرض الحل
using System; using System.Collections.Generic; class Program { static void Main() { List<int> numbers = new List<int>(); while (true) { Console.Write("أدخل رقم أو اكتب exit للخروج: "); string input = Console.ReadLine(); if (input == "exit") { break; } int n = int.Parse(input); numbers.Add(n); } Console.WriteLine("الأرقام المدخلة:"); for (int i = 0; i < numbers.Count; i++) { Console.WriteLine(numbers[i]); } } }

التمرين 5 — BankAccount + تغليف الرصيد

المطلوب: BankAccount يحتوي:

عرض الحل
using System; class BankAccount { public string FirstName; public string LastName; private int balance; public void SetBalance(int amount) { if (amount >= 0) { balance = amount; } } public int GetBalance() { return balance; } } class Program { static void Main() { BankAccount acc = new BankAccount(); acc.FirstName = "Ahmad"; acc.LastName = "Saleh"; acc.SetBalance(5000); Console.WriteLine(acc.FirstName + " " + acc.LastName); Console.WriteLine("الرصيد: " + acc.GetBalance()); } }

التمرين 6 — Student في List + متوسط العلامات

المطلوب: Student فيه Name و Mark؛ أنشئ كائنين، أضفهما إلى List<Student>، اطبعهم، ثم احسب متوسط العلامات.

عرض الحل
using System; using System.Collections.Generic; class Student { public string Name; public int Mark; } class Program { static void Main() { List<Student> students = new List<Student>(); Student s1 = new Student(); Console.Write("أدخل اسم الطالب الأول: "); s1.Name = Console.ReadLine(); Console.Write("أدخل علامة الطالب الأول: "); s1.Mark = int.Parse(Console.ReadLine()); students.Add(s1); Student s2 = new Student(); Console.Write("أدخل اسم الطالب الثاني: "); s2.Name = Console.ReadLine(); Console.Write("أدخل علامة الطالب الثاني: "); s2.Mark = int.Parse(Console.ReadLine()); students.Add(s2); Console.WriteLine("الطلاب:"); for (int i = 0; i < students.Count; i++) { Console.WriteLine(students[i].Name + " - " + students[i].Mark); } int sum = 0; for (int i = 0; i < students.Count; i++) { sum += students[i].Mark; } double avg = sum / (double)students.Count; Console.WriteLine("متوسط العلامات = " + avg); } }