מדריך #C מתקדם – Operators Overloading – העמסת אופרטורים
ב- #C ניתן להעמיס פונקציות, בנאים ואופרטורים.
העמסת אופרטורים (Operator Overloading) מאפשרת לתת משמעות רצויה לאופרטור כאשר הוא יופעל על המחלקה שלנו. המטרה היא לאפשר הפעלת אופרטורים על המחלקה שלנו או מתן מימוש שונה לאופרטורים שכבר ניתן להפעיל (כגון ==).
התחביר להעמסת אופרטורים מתחלק ל- 2 סוגים:
- אופרטור אונרי (Unary) – הפועל רק על אופרנד אחד, כגון ++a
- אופרטור בינארי (Binary) – הפועל על 2 אופרנדים, כגון a+b
העמסת אופרטור אונרי:
public static Circle operator ++(Circle c)
{
//מימוש
}
מבנה כותרת ההעמסה של אופרטור אונרי יהיה בדיוק בסדר הבא:
- public static
- הערך המוחזר (Circle בדוגמא הנ"ל)
- מילת המפתח operator
- האופרטור שרוצים להעמיס (++ בדוגמא)
- פרמטר מטיפוס המחלקה ( Circle c בדוגמא)
העמסת אופרטור בינארי:
public static Circle operator +(Circle c, int x)
{
//מימוש
}
מבנה כותרת ההעמסה של אופרטור בינארי יהיה בדיוק בסדר הבא:
- public static
- הערך המוחזר (Circle בדוגמא הנ"ל)
- מילת המפתח operator
- האופרטור שרוצים להעמיס (++ בדוגמא)
- פרמטר מטיפוס המחלקה Circle c)בדוגמא)
- פרמטר נוסף, מטיפוס כלשהו (int x בדוגמא)
לדוגמא, מימוש האופרטור ++ (אונרי) והאופרטור + (בינארי) במחלקה Circle:
class Circle
{
public double Radius { get; set; }
public static Circle operator ++(Circle c)
{
c.Radius++;
return c;
}
public static Circle operator +(Circle c, int x)
{
Circle newC = new Circle();
newC.Radius = c.Radius + x;
return newC;
}
}
שימוש באופרטורים:
class Program
{
static void Main(string[] args)
{
Circle c = new Circle() { Radius = 10 };
c++;
Console.WriteLine(c.Radius);
c = c + 5;
Console.WriteLine(c.Radius);
}
}
פלט התוכנית:
האופרטורים הניתנים להעמסה:
אופרטורים בינאריים | + | – | * | / | % | | | ^ | >> | << | & |
אופרטורים אונריים | + | – | ++ | — | ! | ~ | true | false | ||
אופרטורים השוואתיים /לוגיים | == | =! | < | > | =< | => |
האופרטורים שלא ניתנים להעמסה:
אופרטורים מיוחדים | = | . | 😕 | && | || | |
אופרטורים מילות-מפתח | new | is | sizeof | typeof | checked | unchecked |
אופרטורים מורכבים | =+ | =- | =* | =/ | =% | |
סוגריים | ( | ) | [ | ] | { | } |
כללים להעמסת אופרטורים
- מוגדרים תמיד כ- public static
- העמסה של אופרטור השוואתי (לוגי) מחייבת העמסה של האופרטור המנוגד (כולל true,false). לדוגמא, העמסה של == תחייב העמסה גם של =!
- העמסה של אופרטור השוואתי תחזיר ערך בוליאני בלבד
- העמסה של אופרטורים ==, =! מחייבים מימוש הפונקציה Equals ופונקציה זו מחייבת מימוש הפונקציה GetHashCode
- בכדי למנוע בילבול לא מומלץ לשנות את המשמעות המקורית (והמובנת) של האופרטור
העמסת casting
ניתן להעמיס גם את האופרטורים המבצעים casting בין טיפוסים. לדוגמא נרצה לאפשר המרה בין string ל- Circle ובחזרה, ובין double ל- Circle ובחזרה.
תזכורת:
- explicit casting – המרה מפורשת שבה חובה לבצע כתיבת ה- casting
- implicit casting – המרה מרומזת ללא צורך בכתיבת ה- casting
מימוש המרות מפורשות (explicitly casting) –
- המרה מפורשת מ- string ל- Circle :
public static explicit operator Circle(string str)
{
Circle c = new Circle();
c.Radius = double.Parse(str);
return c;
}
- המרה מפורשת מ-double ל- Circle :
public static explicit operator Circle(double dbl)
{
Circle c = new Circle();
c.Radius = dbl;
return c;
}
מימוש המרות מרומזות (implicitly casting) –
- המרה מרומזת מ- Circle ל- string:
public static implicit operator string(Circle c)
{
return c.Radius.ToString();
}
- המרה מרומזת מ- Circle ל- double:
public static implicit operator double(Circle c)
{
return c.Radius;
}
שימוש:
static void Main(string[] args)
{
string str = "9";
//explicitly convert String to Circle:
Circle c1 = (Circle)str;
Console.WriteLine(c1.Radius);
double dbl = 7;
//explicitly convert Double to Circle:
Circle c2 = (Circle)dbl;
Console.WriteLine(c2.Radius);
c1 += 10;
str = c1; //implicitly convert Circle to String
Console.WriteLine(str);
c2 += 10;
dbl = c2; //implicitly convert Circle to Double
Console.WriteLine(dbl);
}
פלט התוכנית:
תגובות בפייסבוק