السجلات (Records)
السجلات (Records) في سي شارب تمثل نقلة نوعية في أسلوب التعامل مع البيانات غير القابلة للتغيير (Immutable Data) وتبسيط بناء نماذج البيانات. تم تقديمها لأول مرة في C# 9، وهي مصممة لتقليل الكود المتكرر عند إنشاء كائنات (Classes) تُستخدم غالبًا كـ Data Carriers، أي كائنات تحتوي على بيانات فقط بدون منطق معقد. تعتبر السجلات مهمة لأنها توفر دعماً مدمجاً للـ immutability، وميزة المقارنة حسب القيمة Value Equality، مما يجعلها مثالية لبناء هياكل بيانات تستخدم في الخوارزميات أو في معالجة البيانات ضمن التطبيقات الكبيرة.
يمكن استخدام السجلات عندما نحتاج إلى تمثيل كائنات بيانات ثابتة، مثل User، أو Transaction، أو Product، بحيث يكون الغرض الأساسي هو حمل البيانات لا تنفيذ سلوكيات معقدة. ومن منظور برمجة الكائنات (OOP)، السجلات تتيح أسلوباً حديثاً يتكامل مع مبادئ الكبسلة (Encapsulation) والتجريد (Abstraction). كما أن استخدامها في بنية البرمجيات يساهم في تحسين الأداء والتصميم النظيف (Clean Architecture) وتقليل الأخطاء الناجمة عن التعديل غير المقصود على الكائنات.
في هذا الدرس، سيتعلم القارئ كيفية إنشاء السجلات في سي شارب، كيفية تطبيقها عملياً مع الخوارزميات، وكيفية الاستفادة منها ضمن سياقات معمارية أوسع مثل الطبقات (Layers) أو الخدمات (Services). الهدف هو تمكين المطور من استخدام السجلات بطريقة احترافية تساهم في كتابة كود نظيف، فعال، وآمن ضمن مشاريع سي شارب متقدمة.
مثال أساسي
textusing System;
public record User(string Name, int Age);
public class Program
{
public static void Main()
{
User user1 = new("Ali", 25);
User user2 = new("Ali", 25);
User user3 = new("Sara", 30);
Console.WriteLine($"user1 == user2: {user1 == user2}");
Console.WriteLine($"user1 == user3: {user1 == user3}");
// نسخ مع تعديل قيمة
User updatedUser = user1 with { Age = 26 };
Console.WriteLine($"Updated User: {updatedUser.Name}, {updatedUser.Age}");
}
}
الكود السابق يعرض مثالاً أساسياً لاستخدام السجلات (Records) في سي شارب. قمنا أولاً بتعريف سجل باسم User يحتوي على خاصيتين: Name و Age. ميزة السجلات هنا أنها تدعم المقارنة بالقيمة (Value Equality) بشكل افتراضي، بمعنى أن كائنين من نفس النوع ولهما نفس القيم الداخلية سيتم اعتبارهما متساويين. في الكود، عند مقارنة user1 و user2، النتيجة True رغم أنهما كائنان مختلفان في الذاكرة، وذلك لأن القيم متطابقة. أما user1 و user3 فغير متساويين لأن القيم مختلفة.
كذلك، عرضنا كيفية إنشاء نسخة معدلة من سجل موجود باستخدام كلمة with. هذه الميزة مهمة لأنها تتيح تعديل البيانات بطريقة آمنة دون تغيير الكائن الأصلي، مما يعزز مبدأ immutability.
من ناحية أفضل الممارسات في سي شارب، فإن استخدام السجلات يقلل من الأخطاء الناتجة عن التلاعب غير المقصود بالكائنات. كما أنه يجعل الكود أكثر وضوحاً ومرونة عند بناء تطبيقات تتعامل مع بيانات كثيرة مثل أنظمة الحسابات أو أنظمة الهوية. على مستوى معمارية النظم، السجلات تساعد على بناء DTOs (Data Transfer Objects) تُستخدم في تمرير البيانات بين الطبقات. بهذا الشكل، يمكن للمطور كتابة خوارزميات تعتمد على مقارنة البيانات دون الحاجة إلى كتابة منطق إضافي للمقارنة أو النسخ.
مثال عملي
textusing System;
using System.Collections.Generic;
public record Product(int Id, string Name, decimal Price);
public class Order
{
public int OrderId { get; init; }
public List<Product> Products { get; init; } = new();
public decimal CalculateTotal()
{
decimal total = 0;
foreach (var product in Products)
{
total += product.Price;
}
return total;
}
}
public class Program
{
public static void Main()
{
Product p1 = new(1, "Laptop", 1500m);
Product p2 = new(2, "Mouse", 50m);
Product p3 = new(3, "Keyboard", 100m);
Order order = new()
{
OrderId = 101,
Products = new List<Product> { p1, p2, p3 }
};
Console.WriteLine($"Order ID: {order.OrderId}");
Console.WriteLine($"Total Price: {order.CalculateTotal()}");
// استخدام السجل للمقارنة
Product duplicate = new(1, "Laptop", 1500m);
Console.WriteLine($"p1 == duplicate: {p1 == duplicate}");
}
}
سي شارب best practices and common pitfalls:
من أفضل الممارسات عند استخدام السجلات في سي شارب أن نستخدمها لتمثيل البيانات غير القابلة للتغيير (Immutable Data) وتجنب استخدامها حيث يتطلب الأمر تغيير الحالة باستمرار. يجب الاعتماد على بناء خصائص init فقط لضمان immutability. كما يُفضل استخدام كلمة with لإنشاء نسخ معدلة من السجل بدلاً من تعديل الكائن الأصلي.
من الأخطاء الشائعة التي يجب تجنبها استخدام السجلات كبدائل كاملة للفئات (Classes) في كل الحالات، حيث أن الفئات ما زالت مناسبة عندما نحتاج إلى منطق معقد أو mutable state. خطأ آخر شائع هو الاعتماد على المقارنة الافتراضية دون إدراك أنها تعتمد على القيم الداخلية، ما قد يسبب لبساً إذا كانت بعض الخصائص غير مهمة للمقارنة.
بالنسبة لمشكلات الأداء، يجب الحذر من إنشاء نسخ متكررة من السجلات في الحلقات الكبيرة، حيث أن ذلك قد يزيد الضغط على Garbage Collector. أما من الناحية الأمنية، فيجب تجنب كشف البيانات الحساسة مباشرة عبر ToString الافتراضية في السجلات، ويمكن تجاوزها (Override) لضبط الإخراج.
في حالة الأخطاء، ينبغي استخدام استثناءات واضحة عند التعامل مع بيانات غير صحيحة. أما لتصحيح الأخطاء، يمكن الاعتماد على Debugger لفحص القيم الداخلية أو استخدام أدوات تحليلية مثل Visual Studio Diagnostics لفهم تدفق البيانات داخل السجلات.
📊 جدول مرجعي
سي شارب Element/Concept | Description | Usage Example |
---|---|---|
record keyword | تعريف نوع سجل جديد غير قابل للتغيير | public record User(string Name, int Age); |
with expression | إنشاء نسخة معدلة من سجل | var newUser = oldUser with { Age = 30 }; |
Value Equality | مقارنة السجلات حسب القيم | Console.WriteLine(user1 == user2); |
Positional Parameters | تعريف الخصائص مباشرة عبر البارامترات | public record Product(int Id, string Name); |
init accessor | تحديد الخصائص كـ immutable | public int Id { get; init; } |
الخلاصة والخطوات التالية في سي شارب:
تعلمنا في هذا الدرس أن السجلات (Records) في سي شارب أداة قوية لتبسيط العمل مع البيانات غير القابلة للتغيير، حيث توفر دعمًا مدمجًا للمقارنة حسب القيمة وإنشاء نسخ معدلة من الكائنات بسهولة. تعتبر السجلات مثالية لبناء نماذج بيانات، DTOs، وهياكل تستخدم في أنظمة متقدمة مثل نظم الفوترة أو تطبيقات الويب المعقدة.
هذه المفاهيم ترتبط ارتباطًا وثيقًا بالتصميم النظيف Clean Architecture، حيث تساعد على فصل البيانات عن المنطق المعقد، مما يسهل الاختبار وإعادة الاستخدام. من المواضيع التالية الموصى بدراستها بعد السجلات: التعبيرات النمطية (Pattern Matching) المتقدمة، LINQ مع السجلات، تصميم DTOs و ViewModels باستخدام السجلات، والفرق بين الـ Classes و Structs و Records في سيناريوهات الأداء.
للتطبيق العملي، يُنصح بدمج السجلات في مشاريع حقيقية مثل تطوير واجهات برمجية (APIs) أو أنظمة معالجة بيانات، مما يعزز الفهم ويكشف التحديات الواقعية. المصادر الإضافية تشمل الوثائق الرسمية لمايكروسوفت، وكتب متقدمة في سي شارب مثل "C# in Depth". بذلك يمكن للمطور بناء كفاءة قوية في استخدام السجلات ضمن بيئات الإنتاج.
🧠 اختبر معرفتك
Test Your Knowledge
Test your understanding of this topic with practical questions.
📝 التعليمات
- اقرأ كل سؤال بعناية
- اختر أفضل إجابة لكل سؤال
- يمكنك إعادة الاختبار عدة مرات كما تريد
- سيتم عرض تقدمك في الأعلى