Wyobraźmy sobie taką oto sytuację, że utworzony został pewien zbiór obiektów geometrycznych, z których każdy może się przemieszczać w pewnej funkcji czasu i gdy piszę, że może to znaczy że obiekt ten nie musi koniecznie się przemieszczać. A więc, jeżeli przemieszczenie obiektu jest zerowe to obiekt się nie przemieszcza, a jeżeli jest różne od zera to się przemieszcza. Przemieszczenie obiektu nazwijmy sobie zdarzeniem, w reakcji na to zdarzenie obiekt wywołuje pewien zbiór funkcji, tak zwanych delegatów, które mają za zadanie poinformować wszystkie inne obiekty o tym, że ten konkretny obiekt się przemieścił. W odpowiedzi na to każdy z pozostałych obiektów sprawdza, czy nie nastąpiła jego kolizja z obiektem wysyłającym zgłoszenie zdarzenia.
Najczęściej zdarzenia będą spotykane przy tworzeniu programów okienkowych w C#, np zdarzenie Click dla przycisku.
public delegate void collision(circle c); // tworzenie typu delegata
public class circle : Point2D
{
protected uint ray;
public event collision col; // tworzenie zdarzenia, które będzie wywoływane, gdy obiekt będzie się przemieszczał
public uint Ray
{
get { return ray; }
set { ray = value; }
}
public circle()
{
ray = 0;
col = null;
}
public circle(uint ray, double x, double y)
: base(x, y)
{
this.ray = ray;
col = null;
}
public void move(double dx, double dy)
{
X += dx;
Y += dy;
if (dx != 0 || dy != 0)
{
if (col != null)
{
col(this); // tutaj wywoływane będą wszystkie funkcje przypisane do zdarzenia
}
}
}
public void collision_reaction(circle c) // ta metoda będzie wykorzystywana do generowania reakcji na zdarzenie
{
if (Math.Sqrt((c.X - X) * (c.X - X) + (c.Y - Y) * (c.Y - Y)) <= c.Ray + ray)
{
Console.WriteLine("okrąg o współrzędnych: x = " + c.X + "; y = " + c.Y + "; i promieniu r = " + c.Ray);
Console.WriteLine("koliduje z okrągiem o współrzędnych: x = " + X + "; y = " + Y + "; i promieniu r = " + Ray);
}
else
{
Console.WriteLine("brak zderzenia");
}
}
}
W powyższym kodzie utworzony został typ delegacji collision (kolizja), który określa jaki typ metod może on przechowywać, ponieważ w przypadku, gdy dany delegat zwraca typ void to taki delegat przechowuje listę metod, które w reakcji na jego wywołanie kolejno będą wywoływane. Utworzenie zdarzenia ma miejsce wewnątrz klasy i jest ono ściśle powiązane z utworzeniem obiektu delegacji z wykorzystaniem słowa kluczowego event (zdarzenie). Klasa circle będzie wywoływała zdarzenie col, gdy dojdzie do przemieszczenia tegoż obiektu w celu obsłużenia wykrycia i reakcji na ewentualną kolizję.
A oto kod, który wywołuje odpowiedź na zdarzenie col:
var c1 = new circle(10, 100, 0);
var c2 = new circle(10, 10, 0);
c1.col += c2.collision_reaction; // dodanie zdarzenia do obiektu c1 jako metody z obiektu c2
c2.col += c1.collision_reaction; // to samo, tylko że na odwrót
c1.move(-93, 0); // przemieszczenie obiektu wywoła pierwsze zdarzenie mówiące o zderzeniu c1 z c2
c2.move(100,200); // przemieszczenie obiektu wywoła drugie zdarzenie mówiące, że obiekty się nie zderzyły
Console.ReadLine();
Wynik działania powyższego kodu jest następujący:
okrąg o współrzędnych: x = 7; y = 0; i promieniu r = 10
koliduje z okrągiem o współrzędnych: x = 10; y = 0; i promieniu r = 10
brak zderzenia
Możliwe jest również usunięcie danej metody z listy zdarzeń za pomocą operatora -=. Dodatkowo można utworzyć delegację, która zwraca jakąś wartość, w takim przypadku obiekt takiego delegata nie może przyjmować listy metod a jedynie jedną metodę.