تحميل عوامل المقارنة الزائد
نفّذوا عوامل == و!= والترتيب
تحميل عوامل المقارنة الزائد درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.
معاملات المقارنة والمساواة
عند تحميل == تحميلًا زائدًا، يجب عليك أيضًا تحميل != تحميلًا زائدًا، كما ينبغي تجاوز Equals وGetHashCode للحفاظ على اتساق جميع صور المساواة. وتفرض C# اقتران المعاملين وقت الترجمة.
التحميل الزائد لـ == و !=
يفرض المصرّف تعريف == و!= معًا. ويعيد كل منهما قيمة bool تصف ما إذا كانت القيمتان الداخلتان تُعدّان متساويتين.
using System;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Point(1, 2) == new Point(1, 2));
Console.WriteLine(new Point(1, 2) != new Point(3, 4));
}
}تجاوز Equals دائمًا أيضًا
تُحل المعاملات وقت الترجمة وفقًا للنوع الساكن، أما Equals فهو افتراضي وتستخدمه المجموعات. تجاوز Equals لكي تتفق القواميس وList.Contains مع ==.
using System;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
object a = new Point(1, 2);
object b = new Point(1, 2);
Console.WriteLine(a.Equals(b));
}
}يجب أن يتوافق GetHashCode مع المساواة
إذا كانت قيمتان متساويتين، فيجب أن تعيدا رمز التجزئة نفسه. وإلا فستعمل المجموعات المعتمدة على التجزئة، مثل Dictionary وHashSet، بطريقة غير صحيحة.
using System;
using System.Collections.Generic;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
var set = new HashSet<Point> { new Point(1, 2) };
Console.WriteLine(set.Contains(new Point(1, 2)));
}
}معاملات الترتيب < و >
يمكنك أيضًا تحميل معاملات العلاقات تحميلًا زائدًا. وكما هو الحال مع المساواة، يجب تعريف < و> معًا، وكذلك <= و>=.
using System;
public struct Weight
{
public int Grams;
public Weight(int g) { Grams = g; }
public static bool operator <(Weight a, Weight b) => a.Grams < b.Grams;
public static bool operator >(Weight a, Weight b) => a.Grams > b.Grams;
public override string ToString() => Grams + "g";
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Weight(100) < new Weight(200));
Console.WriteLine(new Weight(300) > new Weight(200));
}
}المساواة في الأنواع المرجعية
بالنسبة إلى الفئات، تعني مساواة القيم مقارنة الحقول بدلًا من المراجع. تعامل مع null بحذر لتجنب طرح استثناء من داخل المعامل.
using System;
public class Person
{
public string Name;
public Person(string name) { Name = name; }
public static bool operator ==(Person a, Person b)
{
if (ReferenceEquals(a, b)) return true;
if (a is null || b is null) return false;
return a.Name == b.Name;
}
public static bool operator !=(Person a, Person b) => !(a == b);
public override bool Equals(object obj) => this == (obj as Person);
public override int GetHashCode() => Name?.GetHashCode() ?? 0;
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Person("Ann") == new Person("Ann"));
}
}الاتساق بين جميع الصيغ
ينبغي أن تتفق جميع طرق التحقق من المساواة: == وEquals ورمز التجزئة. نفّذ == باستخدام Equals (أو العكس) لكي يكون هناك مصدر واحد للحقيقة.
using System;
public struct Id
{
public int Value;
public Id(int value) { Value = value; }
public bool Equals(Id other) => Value == other.Value;
public override bool Equals(object obj) => obj is Id other && Equals(other);
public override int GetHashCode() => Value;
public static bool operator ==(Id a, Id b) => a.Equals(b);
public static bool operator !=(Id a, Id b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Id(7) == new Id(7));
Console.WriteLine(new Id(7).Equals(new Id(8)));
}
}المعاملات مقابل Equals في المجموعات
يستخدم البحث في القوائم Equals، وليس ==، لأنه يعمل مع مراجع من النوع object. وإذا حمّلت == تحميلًا زائدًا فقط ونسيت Equals، فستستخدم عمليات البحث هوية المرجع وقد تفشل.
using System;
using System.Collections.Generic;
public struct Tag
{
public string Name;
public Tag(string name) { Name = name; }
public override bool Equals(object obj) => obj is Tag t && t.Name == Name;
public override int GetHashCode() => Name?.GetHashCode() ?? 0;
public static bool operator ==(Tag a, Tag b) => a.Equals(b);
public static bool operator !=(Tag a, Tag b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var list = new List<Tag> { new Tag("red"), new Tag("blue") };
Console.WriteLine(list.Contains(new Tag("blue")));
}
}إسكات تحذيرات المصرّف بطريقة صحيحة
لا يُعد تجاوز Equals وGetHashCode إلى جانب المعاملات مجرد التزام بالأسلوب؛ إذ يصدر المصرّف تحذيرًا إذا حمّلت == تحميلًا زائدًا من دون تجاوز Equals. ويؤدي تنفيذ الأمرين إلى إزالة التحذير ومنع الأخطاء.
using System;
public struct Cell
{
public int Row, Col;
public Cell(int r, int c) { Row = r; Col = c; }
public override bool Equals(object obj) => obj is Cell c && c.Row == Row && c.Col == Col;
public override int GetHashCode() => HashCode.Combine(Row, Col);
public static bool operator ==(Cell a, Cell b) => a.Equals(b);
public static bool operator !=(Cell a, Cell b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Cell(0, 0) == new Cell(0, 0));
}
}جمع كل الأجزاء
يعرّف النوع القابل للمساواة والسليم == و!=، ويتجاوز Equals وGetHashCode، ويوجّهها جميعًا عبر مقارنة واحدة. وهذا هو المعيار الذهبي للأنواع الشبيهة بالقيم.
using System;
using System.Collections.Generic;
public struct Color
{
public int R, G, B;
public Color(int r, int g, int b) { R = r; G = g; B = b; }
public override bool Equals(object obj) => obj is Color c && c.R == R && c.G == G && c.B == B;
public override int GetHashCode() => HashCode.Combine(R, G, B);
public static bool operator ==(Color a, Color b) => a.Equals(b);
public static bool operator !=(Color a, Color b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var dict = new Dictionary<Color, string> { [new Color(255, 0, 0)] = "red" };
Console.WriteLine(dict[new Color(255, 0, 0)]);
}
}جرّب بنفسك
نفّذ بنية قابلة للمساواة ومتسقة تمامًا، وتحقق من أنها تعمل في الوقت نفسه كمفتاح لقاموس ومعامل ==.
using System;
using System.Collections.Generic;
public struct GridPos
{
public int Row, Col;
public GridPos(int r, int c) { Row = r; Col = c; }
public override bool Equals(object obj) => obj is GridPos p && p.Row == Row && p.Col == Col;
public override int GetHashCode() => HashCode.Combine(Row, Col);
public static bool operator ==(GridPos a, GridPos b) => a.Equals(b);
public static bool operator !=(GridPos a, GridPos b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var grid = new Dictionary<GridPos, string> { [new GridPos(1, 1)] = "player" };
Console.WriteLine(new GridPos(1, 1) == new GridPos(1, 1));
Console.WriteLine(grid[new GridPos(1, 1)]);
}
}تحقق سريع
تذكّر قواعد التحميل الزائد للمساواة.
مراجعة
يتطلب تحميل معاملات المقارنة تحميلًا زائدًا الحفاظ على الاتساق.
- يجب تعريف
==و!=معًا، وكذلك</>. - تجاوز
EqualsوGetHashCodeليتوافقا مع==. - يجب أن تشترك القيم المتساوية في رمز تجزئة واحد.
- وجّه جميع عمليات التحقق من المساواة عبر أسلوب مقارنة واحد لتجنب التباين.
الأسئلة الشائعة
هل درس «تحميل عوامل المقارنة الزائد» مجاني؟
نعم — نص درس «تحميل عوامل المقارنة الزائد» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.
ماذا ستتعلم في «تحميل عوامل المقارنة الزائد»؟
نفّذوا عوامل == و!= والترتيب تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «تحميل عوامل المقارنة الزائد»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تحميل عوامل الحساب الزائد
- تحميل عوامل المقارنة الزائد
- التحويلات المعرّفة من المستخدم
- أفضل ممارسات تحميل العوامل الزائد