Операции C# | Возможность перегрузки |
---|---|
+, -, !, ~, ++, --, true, false | Эти унарные операции допускают перегрузку |
+, -, *, /, %, &, |, ^, ‹‹, ›› | Эти бинарные операции допускают перегрузку |
==, !=, ‹, ›, ‹=, ›= | Операции сравнения допускают перегрузку. В C# требуется, чтобы перегрузка "родственных" операций (т.е. ‹ и |
[] | Операция [] не допускает перегрузку. Но, как было показано выше, аналогичные перегрузке возможности обеспечивает конструкция индексатора |
Операция не допускает перегрузку. Но, как будет показано ниже, аналогичные перегрузке возможности обеспечивают пользовательские методы преобразования | |
+=, -=, *=, /=, %=, &=, |=, ^=, ‹‹=, ››= | Операторные сокращения с присваиванием сами по себе не допускают перегрузку, однако для них перегруженная форма получается автоматически в результате перегрузки соответствующей бинарной операции |
Перегрузка бинарных операций
Чтобы проиллюстрировать процесс перегрузки бинарных операций, расcмо-трим следующую простую структуру Point (точка).
// Самая обычная структура C#.
public struct Point {
private int x, y;
public Point(int xPos, int yPos) {
x = xPos
}
public override string ToString {
return string.Format("[{0}, {1}]", this.x, this.у);
}
}
Можно, скажем, рассмотреть сложение типов Point. Можно также вычесть один тип Point из другого. Например, вы можете записать, следующий программный код.
// Сложение и вычитание двух точек.
static vоid Main(string [] args) {
Console.WriteLine("*** Забавы с перегруженными операциями ***\n");
// Создание двух точек.
Point ptOne = new Point(100, 100);
Point ptTwo = new Point (40, 40);
Console.WriteLine("ptOne = {0}", ptOne);
Console.WriteLine("ptTwo = {0}", ptTwo);
// Сложение точек в одну большую точку?
Console.WriteLine("ptOne + ptTwo: {0} ", ptOne + ptTwo);
// Вычитание одной точки из другой дает меньшую точку?
Console.WriteLine("ptOne – ptTwo: {0} ", ptOne – ptTwo);
Console.ReadLine;
}
Чтобы позволить пользовательскому типу по-своему отвечать на встроенные операции, в C# предлагается ключевое слово operator, которое можно использовать только со
// Более 'интеллектуальный' тип Point.
public struct Point {
…
// перегруженная операция +
public static Point operator+(Point p1, Point p2) { return new Point(p1.x + p2.x, p1.y + p2.y); }
// перегруженная операция -
public static Point operator–(Point p1, Point p2) { return new Point(p1.x – p2.x, p1.y – p2.y); }
}
По логике операция + должна просто возвратить совершенно новый объект Point, полученный в результате суммирования соответствующих полей входных параметров Point. Поэтому, когда вы пишете pt1 + pt2, можете представлять себе следующий скрытый вызов статического метода операции +.
// р3 = Point.операция+(p1, р2)
р3 = p1 + р2;
Точно так же p2 – p2 отображается в следующее.