مساواة القيم والتفكيك
افهموا المساواة البنيوية في records، وتجاوزوا Equals/GetHashCode، واستخدموا أنماط التفكيك.
مساواة القيم والتفكيك درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.
تعمّق في مساواة السجلات
تنشئ السجلات تلقائيًا Equals وGetHashCode والعاملين ==/!= لمقارنة جميع الخصائص بنيويًا. ويساعدك فهم آلية ذلك على استخدام السجلات بصورة صحيحة وتجاوز السلوك الافتراضي عند الحاجة.
كيفية عمل المساواة المُنشأة تلقائيًا
ينشئ المترجم تعليمات برمجية تقارن كل خاصية باستخدام EqualityComparer<T>.Default. وبالنسبة إلى خصائص الأنواع المرجعية، تستخدم هذه العملية Equals الخاصة بها، لا مساواة المراجع.
public record Address(string Street, string City);
public record Person(string Name, Address HomeAddress);
var a = new Person("Alice", new Address("123 Main", "NYC"));
var b = new Person("Alice", new Address("123 Main", "NYC"));
Console.WriteLine(a == b); // True — deep structural equality
// Equality checks:
// Name: "Alice" == "Alice" ✓
// HomeAddress: compares Address properties recursively ✓تجاوز المساواة المُنشأة تلقائيًا
يمكنك تجاوز Equals وGetHashCode في السجل عندما تريد منطقًا مخصصًا للمساواة، مثل مقارنة مجموعة فرعية من الخصائص فقط.
public record Customer(int Id, string Name, string Email)
{
// Consider customers equal if they have the same ID,
// regardless of name or email changes
public virtual bool Equals(Customer? other)
=> other is not null && Id == other.Id;
public override int GetHashCode() => Id.GetHashCode();
}السجلات في المجموعات
بما أن السجلات تنفّذ IEquatable<T> مع المساواة البنيوية، فإنها تعمل بصورة صحيحة كمفاتيح للقواميس، وفي HashSets، ومع Distinct وGroupBy في LINQ.
public record Tag(string Name, string Color);
var tags = new List<Tag>
{
new("C#", "blue"), new("C#", "blue"), new("dotnet", "purple")
};
var unique = tags.Distinct().ToList(); // [Tag(C#, blue), Tag(dotnet, purple)]
var set = new HashSet<Tag>(tags);
set.Contains(new Tag("C#", "blue")); // trueالتفكيك: الأساسيات
تنشئ السجلات الموضعية تلقائيًا طريقة Deconstruct مع معلمات out لكل خاصية موضعية. ويتيح ذلك فك الحزم بطريقة تشبه الصفوف.
public record Point(double X, double Y);
public record RGB(byte R, byte G, byte B);
var p = new Point(3.0, 4.0);
var (x, y) = p; // deconstruct
Console.WriteLine($"{x}, {y}");
var color = new RGB(255, 128, 0);
var (r, g, b) = color;
Console.WriteLine($"R={r}, G={g}, B={b}");التفكيك في مطابقة الأنماط
يتيح تفكيك السجلات في تعبيرات switch إجراء مطابقة قوية للأنماط الموضعية.
public record Point(int X, int Y);
string Classify(Point p) => p switch
{
(0, 0) => "Origin",
(int x, 0) => $"X-axis at {x}",
(0, int y) => $"Y-axis at {y}",
(int x, int y) when x == y => $"Diagonal at {x}",
(int x, int y) => $"Point ({x}, {y})"
};
Console.WriteLine(Classify(new Point(0, 0))); // Origin
Console.WriteLine(Classify(new Point(3, 3))); // Diagonal at 3طرق Deconstruct مخصصة
يمكن للسجلات غير الموضعية (وأي فئة) إضافة طريقة Deconstruct يدويًا. كما يمكن لطرق الامتداد إضافة التفكيك إلى الأنواع الموجودة.
public class Temperature
{
public double Celsius { get; }
public Temperature(double c) => Celsius = c;
// Manual Deconstruct
public void Deconstruct(out double celsius, out double fahrenheit)
{
celsius = Celsius;
fahrenheit = Celsius * 9 / 5 + 32;
}
}
var t = new Temperature(100);
var (c, f) = t;
Console.WriteLine($"{c}°C = {f}°F"); // 100°C = 212°Fتجاهل أجزاء من التفكيك
استخدم القيم المتجاهلة (_) لتجاهل الأجزاء غير المطلوبة من عملية التفكيك، على نحو يشبه القيم المتجاهلة في الصفوف.
public record Order(int Id, string Customer, decimal Total, DateTime Date);
var order = new Order(42, "Alice", 99.99m, DateTime.UtcNow);
// Only want Id and Total
var (id, _, total, _) = order;
Console.WriteLine($"Order {id}: ${total}");
// In switch: ignore some fields
string Classify(Order o) => o switch
{
(_, _, > 1000, _) => "High value",
(_, _, > 100, _) => "Medium value",
_ => "Low value"
};أنماط الخصائص مقابل الأنماط الموضعية
تدعم السجلات الأنماط الموضعية (حسب الموضع) وأنماط الخصائص (حسب الاسم). وتكون أنماط الخصائص أوضح قراءةً في السجلات التي تحتوي على خصائص كثيرة.
public record Order(int Id, string Status, decimal Total);
// Positional pattern:
string DescribePos(Order o) => o switch
{
(_, "Shipped", > 100) => "High-value shipped",
_ => "Other"
};
// Property pattern (more readable):
string DescribeProp(Order o) => o switch
{
{ Status: "Shipped", Total: > 100 } => "High-value shipped",
{ Status: "Cancelled" } => "Cancelled",
_ => "Other"
};من الواقع العملي: نمط نوع Result
نوع نتيجة على نمط الاتحاد المميّز، باستخدام السجلات والتفكيك؛ وهو أسلوب وظيفي لمعالجة الأخطاء.
public abstract record Result<T>;
public record Success<T>(T Value) : Result<T>;
public record Failure<T>(string Error) : Result<T>;
Result<Order> PlaceOrder(CreateOrderRequest req)
{
if (req.Quantity <= 0)
return new Failure<Order>("Quantity must be positive");
var order = CreateOrder(req);
return new Success<Order>(order);
}
// Consuming:
var result = PlaceOrder(request);
switch (result)
{
case Success<Order>(var order):
return Results.Created($"/orders/{order.Id}", order);
case Failure<Order>(var error):
return Results.BadRequest(error);
}اختبار سريع
ماذا يفعل استخدام قيمة متجاهلة (_) في تعبير التفكيك؟
مراجعة: المساواة بالقيمة والتفكيك
أهم النقاط المستخلصة:
- تقارن المساواة المُنشأة تلقائيًا جميع الخصائص بنيويًا وبشكل递اعي
- تجاوز Equals/GetHashCode في السجلات لتطبيق منطق مخصص للهوية
- تعمل السجلات بشكل صحيح كعناصر في HashSet وكمفاتيح في القواميس
- تُنشئ السجلات الموضعية Deconstruct تلقائيًا — استخدم var (a, b) = record
- تتجاهل القيم غير المرغوب فيها في التفكيك باستخدام (_)
- تكون أنماط الخصائص ({Status: "X"}) أوضح من الأنماط الموضعية عند التعامل مع السجلات المعقدة
الأسئلة الشائعة
هل درس «مساواة القيم والتفكيك» مجاني؟
نعم — نص درس «مساواة القيم والتفكيك» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.
ماذا ستتعلم في «مساواة القيم والتفكيك»؟
افهموا المساواة البنيوية في records، وتجاوزوا Equals/GetHashCode، واستخدموا أنماط التفكيك. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «مساواة القيم والتفكيك»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أنواع Record: الأساسيات وبناء الجملة
- عدم قابلية التغيير باستخدام init وwith
- مساواة القيم والتفكيك
- Records في التصميم المستند إلى النطاق