Obsługa operatorów struktur i klas

Stronę tą wyświetlono już: 235 razy

Wstęp

Obsługa operatorów klas i struktur w C# jest w zasadzie taka sama. Oto podstawowy zestaw operatorów matematycznych, które można obsłużyć to:

  • + operator dodawania;
  • - operator odejmowania;
  • ++ inkrementacja (zwiększanie wartości o jeden);
  • -- dekrementacja (zmniejszanie wartości o jeden);
  • * operator mnożenia;
  • / operator dzielenia;
  • % operator dzielenia modulo;
  • ! operator zaprzeczenia not;
  • == operator logiczny równości;
  • != operator logiczny nierówności;
  • ~ operator bitowego dopełnienia;
  • << operator bitowego przesunięcia w lewo;
  • >> operator bitowego przesunięcia w prawo;
  • < operator mniejsze niż;
  • > operator większości;
  • <= operator mniejsze równe;
  • >= operator większe równe;
  • & operator bitowej koniunkcji AND;
  • | operator bitowej alternatywy OR;
  • ^ operator bitowej alternatywy wykluczającej XOR;

Dodatkowo możliwe jest obsłużenie rzutowania jednego typu danych na drugi.

Przykładowa implementacja obsługi operatorów klasy Point2D

Oto przykład implementacji podstawowych operatorów w klasie, którą już wcześniej została utworzona przy okazji omawiania tematu Programowanie → Podstawy C# → Klasy:

Listing 1
  1. // ########################### DEKLARACJA KLASY POINT2D #############################
  2. public class Point2D
  3. {
  4. // ####################### CHRONIONE POLA KLASY #################################
  5. protected double x;
  6. protected double y;
  7. // ####################### KONSTRUKTORY KLASY ###################################
  8. public Point2D() // konstruktor zerujący
  9. {
  10. x = y = 0;
  11. }
  12. public Point2D(double x, double y) // konstruktor ustawiajacy
  13. {
  14. this.x = x;
  15. this.y = y;
  16. }
  17. public Point2D(Point2D p) // kosntruktor kopiujący
  18. {
  19. this.x = p.x;
  20. this.y = p.y;
  21. }
  22. // ######## WŁAŚCIWOŚCI KLASY ##########
  23. public double Y
  24. {
  25. get { return y; }
  26. set { y = value; }
  27. }
  28. public double X
  29. {
  30. get { return x; }
  31. set { x = value; }
  32. }
  33. public double Length
  34. {
  35. get { return Math.Sqrt(x * x + y * y); } // pobieranie długości wektora
  36. set // ustawianie długości wektora
  37. {
  38. if (x != 0 || y != 0) // gdy wektor nie jest zerowy to
  39. {
  40. double k = value / Length;
  41. x *= k; // skalowanie składowej x wektora
  42. y *= k; // skalowanie składowej y wektora
  43. }
  44. }
  45. }
  46. // ########### METODY #############
  47. public override string ToString() // przeładowana metoda ToString klasy bazowej Object
  48. {
  49. return "Point2D x = " + x + "; y = " + y;
  50. }
  51. // ########## OPERATORY MATEMATYCZNE ###########
  52. public static Point2D operator +(Point2D p, Point2D p2)
  53. {
  54. return new Point2D(p.x + p2.x, p.y + p2.y);
  55. }
  56. public static Point2D operator -(Point2D p, Point2D p2)
  57. {
  58. return new Point2D(p.x - p2.x, p.y - p2.y);
  59. }
  60. public static double operator *(Point2D p, Point2D p2) // iloczyn skalarny dwóch wektorów
  61. {
  62. return p.x * p2.x + p.y * p2.y;
  63. }
  64. public static Point2D operator *(Point2D p, double k) // iloczyn wektora przez skalar
  65. {
  66. return new Point2D(p.x * k, p.y * k);
  67. }
  68. public static Point2D operator *(double k, Point2D p) // to samo co powyżej, tylko że double jest po lewej stronie
  69. {
  70. return p * k;
  71. }
  72. // ################## OPERATORY PORÓWNANIA WARTOŚCI ##################
  73. public static bool operator ==(Point2D p, Point2D p2)
  74. {
  75. return p.x == p2.x && p.y == p2.y;
  76. }
  77. public static bool operator !=(Point2D p, Point2D p2)
  78. {
  79. return p.x != p2.x || p.y != p2.y;
  80. }
  81. public static bool operator ==(Point2D p, double k)
  82. {
  83. return p.Length == k;
  84. }
  85. public static bool operator ==(double k, Point2D p)
  86. {
  87. return p.Length == k;
  88. }
  89. public static bool operator !=(Point2D p, double k)
  90. {
  91. return p.Length != k;
  92. }
  93. public static bool operator !=(double k, Point2D p)
  94. {
  95. return p.Length != k;
  96. }
  97. public static bool operator <(Point2D p, Point2D p2)
  98. {
  99. return p.Length < p2.Length;
  100. }
  101. public static bool operator <(Point2D p, double k)
  102. {
  103. return p.Length < k;
  104. }
  105. public static bool operator <(double k, Point2D p)
  106. {
  107. return p.Length < k;
  108. }
  109. public static bool operator >(Point2D p, Point2D p2)
  110. {
  111. return p.Length < p2.Length;
  112. }
  113. public static bool operator > (Point2D p, double k)
  114. {
  115. return p.Length > k;
  116. }
  117. public static bool operator > (double k, Point2D p)
  118. {
  119. return p.Length > k;
  120. }
  121. public static bool operator <=(Point2D p, Point2D p2)
  122. {
  123. return p.Length <= p2.Length;
  124. }
  125. public static bool operator <= (Point2D p, double k)
  126. {
  127. return p.Length <= k;
  128. }
  129. public static bool operator <= (double k, Point2D p)
  130. {
  131. return p.Length <= k;
  132. }
  133. public static bool operator >= (Point2D p, Point2D p2)
  134. {
  135. return p.Length >= p2.Length;
  136. }
  137. public static bool operator >= (Point2D p, double k)
  138. {
  139. return p.Length >= k;
  140. }
  141. public static bool operator >= (double k, Point2D p)
  142. {
  143. return p.Length >= k;
  144. }
  145. // ######################## OPERATORY RZUTOWANIA #######################
  146. public static implicit operator double(Point2D p)
  147. {
  148. return p.Length;
  149. }
  150. public static explicit operator long(Point2D p)
  151. {
  152. return (long)p.Length;
  153. }
  154. }

Jak widać przeciążanie operatorów jest jak najbardziej możliwe a nawet wskazane. Dodatkową niespodzianką będzie wykonanie w głównej procedurze programu następującego kodu:

Listing 2
  1. var p2d_1 = new Point2D(10, 20);
  2. var p2d_2 = new Point2D(5, 5);
  3. Console.WriteLine("Suma dwóch wektorów:ttt" + (p2d_1 + p2d_2).ToString());
  4. Console.WriteLine("Różnica dwóch wetkorów:ttt" + (p2d_1 - p2d_2).ToString());
  5. Console.WriteLine("Iloczyn skalarny dwóch wektorów:t" + (p2d_1 * p2d_2).ToString());
  6. var p2d_3 = new Point2D(5, 10);
  7. p2d_3 += p2d_2; // jeżeli zostanie obsłużony operator dodawania to operator dodawania z podstawieniem jest z automatu obsługiwany (to samo tyczy się innych operatorów
  8. Console.WriteLine("Suma dwóch wektorów:ttt" + p2d_3.ToString());
  9. Console.ReadLine();

Proszę zauważyć, że nie obsłużyłem operatora += a jednak go użyłem i to się skompiluje i wykona, wynikiem czego będzie wyświetlanie następującego tekstu:

Suma dwóch wektorów:                    Point2D x = 15; y = 25
Różnica dwóch wetkorów:                 Point2D x = 5; y = 15
Iloczyn skalarny dwóch wektorów:        150
Suma dwóch wektorów:                    Point2D x = 10; y = 15

Komentarze