لماذا هذه الميزات؟
منذ إصدار C# 12 (المرافق لـ .NET 8)، صار بالإمكان كتابة الأصناف والمجموعات بصياغة أقصر بكثير مما رأيته حتى الآن. هذا الدرس يغطّي أهمّ إضافتين انتشرتا في كود C# الحديث: Primary Constructors وتعبيرات المجموعات.
Primary Constructors — مُنشئ مدمج في تعريف الصنف
بدل كتابة مُنشئ منفصل يستقبل معاملات ثم يُسندها لحقول، يمكنك الآن كتابة المعاملات مباشرة بجانب اسم الصنف:
class Car(string brand, int speed)
{
public string Brand { get; } = brand;
public int Speed { get; } = speed;
public void Describe() =>
Console.WriteLine($"{Brand} بسرعة {Speed} كم/س");
}
Car c = new Car("تويوتا", 120);
c.Describe();
معاملات المُنشئ الأساسي (brand وspeed) متاحة في كل جسم الصنف، وليس فقط داخل المُنشئ نفسه — يمكنك استخدامها في الدوال أو الخصائص مباشرة كما في المثال أعلاه.
هذه الميزة كانت حصرًا على record منذ C# 9 (رأيتها في درس Records)، والآن صارت متاحة لأي class أو struct عادي.
💡 على عكس
record، الصنف العادي مع Primary Constructor لا يولّد خصائص عامّة تلقائيًا من معاملاته — عليك تعريف الخاصية صراحة كما فيBrandأعلاه إن أردت الوصول لها من خارج الصنف.
مُنشئات إضافية
إن أضفت مُنشئات أخرى، يجب أن تستدعي المُنشئ الأساسي عبر this(...) لضمان تهيئة كل معاملاته:
class Car(string brand, int speed)
{
public string Brand { get; } = brand;
public Car(string brand) : this(brand, 0) { }
}
تعبيرات المجموعات (Collection Expressions)
صياغة موحّدة وموجزة لإنشاء أي نوع مجموعة تقريبًا، بأقواس مربّعة:
int[] numbers = [1, 2, 3, 4, 5];
List<string> names = ["سارة", "براء", "ليلى"];
Span<char> letters = ['a', 'b', 'c'];
نفس الصياغة تعمل مع المصفوفات وList<T> وSpan<T> وأي نوع آخر يدعم التهيئة كمجموعة — بدل تذكّر صياغة مختلفة لكل نوع (new int[] {...} مقابل new List<string> {...}).
العنصر المنتشر (Spread — ..)
يدمج عناصر مجموعة موجودة داخل مجموعة جديدة دون حلقة يدوية:
int[] first = [1, 2, 3];
int[] second = [4, 5, 6];
int[] combined = [.. first, .. second, 100];
// combined = [1, 2, 3, 4, 5, 6, 100]
.. يفكّك أي مجموعة قابلة للتعداد ويضيف عناصرها واحدًا واحدًا في مكانها داخل التعبير. ويمكن استخدام نفس صياغة الأقواس المربّعة لإنشاء مصفوفة مسنّنة (jagged) دفعة واحدة، مثل [[1, 2], [3, 4]] بدل تعريف كل صفّ على حدة.
| الطريقة القديمة | تعبير المجموعة |
|---|---|
new int[] { 1, 2, 3 } | [1, 2, 3] |
new List<string> { "a", "b" } | ["a", "b"] |
دمج مصفوفتين بحلقة for يدوية | [.. a, .. b] |
💡 استخدم تعبيرات المجموعات لتقليل الضجيج البصري، خصوصًا عند تمرير قيم ثابتة مباشرة كوسيط لدالة:
Process([1, 2, 3])بدلProcess(new List<int> { 1, 2, 3 }).
🎯 التالي: الجديد في C# 14 و.NET 10.