Obsługa operatorów struktur i klas

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 2083 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:

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:

// ########################### DEKLARACJA KLASY POINT2D ############################# public class Point2D { // ####################### CHRONIONE POLA KLASY ################################# protected double x; protected double y; // ####################### KONSTRUKTORY KLASY ################################### public Point2D() // konstruktor zerujący { x = y = 0; } public Point2D(double x, double y) // konstruktor ustawiajacy { this.x = x; this.y = y; } public Point2D(Point2D p) // kosntruktor kopiujący { this.x = p.x; this.y = p.y; } // ######## WŁAŚCIWOŚCI KLASY ########## public double Y { get { return y; } set { y = value; } } public double X { get { return x; } set { x = value; } } public double Length { get { return Math.Sqrt(x * x + y * y); } // pobieranie długości wektora set // ustawianie długości wektora { if (x != 0 || y != 0) // gdy wektor nie jest zerowy to { double k = value / Length; x *= k; // skalowanie składowej x wektora y *= k; // skalowanie składowej y wektora } } } // ########### METODY ############# public override string ToString() // przeładowana metoda ToString klasy bazowej Object { return "Point2D x = " + x + "; y = " + y; } // ########## OPERATORY MATEMATYCZNE ########### public static Point2D operator +(Point2D p, Point2D p2) { return new Point2D(p.x + p2.x, p.y + p2.y); } public static Point2D operator -(Point2D p, Point2D p2) { return new Point2D(p.x - p2.x, p.y - p2.y); } public static double operator *(Point2D p, Point2D p2) // iloczyn skalarny dwóch wektorów { return p.x * p2.x + p.y * p2.y; } public static Point2D operator *(Point2D p, double k) // iloczyn wektora przez skalar { return new Point2D(p.x * k, p.y * k); } public static Point2D operator *(double k, Point2D p) // to samo co powyżej, tylko że double jest po lewej stronie { return p * k; } // ################## OPERATORY PORÓWNANIA WARTOŚCI ################## public static bool operator ==(Point2D p, Point2D p2) { return p.x == p2.x && p.y == p2.y; } public static bool operator !=(Point2D p, Point2D p2) { return p.x != p2.x || p.y != p2.y; } public static bool operator ==(Point2D p, double k) { return p.Length == k; } public static bool operator ==(double k, Point2D p) { return p.Length == k; } public static bool operator !=(Point2D p, double k) { return p.Length != k; } public static bool operator !=(double k, Point2D p) { return p.Length != k; } public static bool operator <(Point2D p, Point2D p2) { return p.Length < p2.Length; } public static bool operator <(Point2D p, double k) { return p.Length < k; } public static bool operator <(double k, Point2D p) { return p.Length < k; } public static bool operator >(Point2D p, Point2D p2) { return p.Length < p2.Length; } public static bool operator > (Point2D p, double k) { return p.Length > k; } public static bool operator > (double k, Point2D p) { return p.Length > k; } public static bool operator <=(Point2D p, Point2D p2) { return p.Length <= p2.Length; } public static bool operator <= (Point2D p, double k) { return p.Length <= k; } public static bool operator <= (double k, Point2D p) { return p.Length <= k; } public static bool operator >= (Point2D p, Point2D p2) { return p.Length >= p2.Length; } public static bool operator >= (Point2D p, double k) { return p.Length >= k; } public static bool operator >= (double k, Point2D p) { return p.Length >= k; } // ######################## OPERATORY RZUTOWANIA ####################### public static implicit operator double(Point2D p) { return p.Length; } public static explicit operator long(Point2D p) { return (long)p.Length; } }

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:

var p2d_1 = new Point2D(10, 20); var p2d_2 = new Point2D(5, 5); Console.WriteLine("Suma dwóch wektorów:ttt" + (p2d_1 + p2d_2).ToString()); Console.WriteLine("Różnica dwóch wetkorów:ttt" + (p2d_1 - p2d_2).ToString()); Console.WriteLine("Iloczyn skalarny dwóch wektorów:t" + (p2d_1 * p2d_2).ToString()); var p2d_3 = new Point2D(5, 10); 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 Console.WriteLine("Suma dwóch wektorów:ttt" + p2d_3.ToString()); 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
Propozycje książek