80. implementing == operator

בהמשך לטיפים של השבוע,

ראינו מה זה Equals ואיך אמורים לממש אותו.

כעת נדבר קצת על האופרטור ==.

כאמור, זוהי מתודה סטטית, ולכן קריאה אליה היא יחסית מהירה.

בקשר למימוש הדיפולטי שלה:

עבור value types אין מימוש דיפולטי

עבור reference type המימוש הדיפולטי הוא השוואת referenceים.

קיימות שתי דרכים פופולאריות לממש אותו:

  1. להשאיר דיפולטי של השוואת Referenceים
  2. להחליף את המימוש בקריאה לEquals של האובייקט.

נרצה לעשות את האופציה השנייה בד”כ במקרים הבאים:

  1. בvalue types – מאחר ואחרת לא נוכל להשתמש באופטור
  2. בreference types – כאשר מדובר באובייקט immutable (שאינו בר שינוי), כיוון שאז שוויון של שני אובייקטים הוא שוויון קבוע. למשל, בstring מומש האופרטור == ע”י קריאה לEquals, גם אם שני הstringים אינם מצביעים לאותו reference.

שימו לב שמימוש של האופרטור ==, דורש גם מימוש של האופרטור =!.

ביכולתנו לממש אותו כאוות נפשנו. למרות זאת, נעדיף בד”כ לממש אותו בצורה הטריוויאלית:

1
2
3
4
public static bool operator !=(MyClass a, MyClass b)
{
return !(a == b);
}

אלא אם כן נרצה לעשות משהו מוזר.


אמרנו בתחילת השבוע שלא תמיד Equals ו== הם זהים.

נראה כעת מקרה בו מומשו גם Equals וגם ==, עם זאת המימוש שונה.

למחלקה double יש מימוש לEquals ול==. הם בד"כ מזדהים:

1
2
3
4
5
6
7
8
9
10
11
12
double first = 4;
double second = 4;
if (first == second)
{
// true
}
if (first.Equals(second))
{
// true
}

אבל יש מקרים יוצאי דופן:

1
2
3
4
5
6
7
8
9
10
11
12
double first = double.NaN;
double second = double.NaN;
if (first == second)
{
// false
}
if (first.Equals(second))
{
// true
}

ההיגיון אומר את הדבר הבא:

NaN (Not a number) הוא לא מספר, ולכן אינו זהה לאף מספר אחר

לכן גם אינו זהה לעצמו.

מצד שני, לשני NaNים שונים, יש אותו "ערך" ולכן הם שווים מבחינת Equals.

סופ"ש שווה!

שתף