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