Статья располагается на двух страницах. Первая часть Использование делегатов в событиях на c#.
Теперь приступим к написанию класса Bank:
class Bank
{
private int personID; // айдишник персоны
private decimal bank_account; // счет в банке
/// <summary>
/// сигнатура делегата
/// </summary>
/// <param name="user">обьект
/// который возбудил событие>/param>
/// <param name="ment">обьект класса SecurytyMonitor
/// который унаследован от класса EventArgs</param>
public delegate void MyDelegate
(object user, SecurytyMonitor ment);
/// <summary>
/// событие типа делегата MyDelegate
/// </summary>
public event MyDelegate OnStop;
/// <summary>
/// конструктор с двумя параметрами
/// </summary>
/// <param name="personID">айдишник персоны</param>
/// <param name="bank_account">деньги,
/// которые ложим в банк>/param>
public Bank(int personID, decimal bank_account)
{
// если сума (bank_account) меньше 0, возбуждаем событие
if (bank_account < 0)
{
// Создаем объект класса SecurytyMonitor
// и формируем текстовое сообщение
SecurytyMonitor sc = new SecurytyMonitor(
"Сума которую можно положить на счет " +
"не должна быть Меньше 0$");
// вызываем метод который подпишет наше событие
// в качестве параметра передаем объект,
// который возбудил событие
sc.DoEvent(this);
// this - обьект который возбудил событие
// sc - обьект класса SecurytyMonitor
OnStop(this, sc);
}
else // иначе все в порядке, устанавливаем значения
{
this.personID = personID;
this.bank_account = bank_account;
}
}
/// <summary>
/// выводим на екран
/// </summary>
public void Show()
{
Console.WriteLine("Unique ID: {0};\nBank account: {1};\n",
this.personID, this.bank_account);
}
/// <summary>
/// метод для снятия денег со счета
/// </summary>
/// <param name="money"<сума, которою надо снять</param>
public void TakeOfMony(decimal money)
{
// если указаная сума (money) больше
// чем есть на счету, возбуждаем событие
if (money > this.bank_account)
{
// Создаем обьект класса SecurytyMonitor
// и формируем текстовое сообщение
SecurytyMonitor sc = new SecurytyMonitor(
"Максимальная сума которую Вы можете снять " +
"со своего счета составляет:" + this.bank_account);
// вызываем метод который подпишет наше событие
// в качестве параметра передаем обьект
// который возбудил событие
sc.DoEvent(this);
// this - обьект который возбудил событие
// sc - обьект класса SecurytyMonitor
OnStop(this, sc);
}
else // все впорядке, снимаем деньги
this.bank_account = bank_account - money;
}
}
Первый параметр, это объект, который возбудил событие, второй параметр, это обьект класса SecurytyMonitor который унаследован от класса EventArgs. А вот и сам класс SecurytyMonitor:
class SecurytyMonitor:EventArgs
{
private string message; // сообщение
/// <summary>
/// свойство для чтения сообщения
/// </summary>
public string Message
{
get { return message; }
}
/// <summary>
/// конструктор с одним параметром
/// </summary>
/// <param name="msg"<текстовое сообщение</param>
public SecurytyMonitor(string msg)
{
message = msg;
}
/// <summary>
/// подписывает событие на метод,
/// который вызывается при возбуждение события
/// </summary>
/// <param name="b">
/// обьект класса Bank,
/// с помощью которго мы доступаемся к событию
/// </param>
public void DoEvent(Bank b)
{
b.OnStop+= new Bank.MyDelegate(Display);
}
/// <summary>
/// выводит сообщение, полученое при возбуждение события
/// </summary>
/// <param name="o">обьект который возбудил событие </param>
/// <param name="sc">обьект класса SecurytyMonitor,
/// который унаследован от EventArgs
/// </param>
public void Display(object o, SecurytyMonitor sc)
{
Console.WriteLine(sc.Message);
}
}
В этом классе объявлено событие OnStop и класс делегата описанный ранее. Как видим, что при создание счета, происходит проверка, прежде чем наполнить счет деньгами. Так же, в этом классе определен метод, который дает возможность снять деньги со счета. В этом методе проверяется наличие денег на счету и сума, которую указал объект. Если сума больше чем денег на счету, возбуждается событие! Как в первом случае при внесение денег на счет, так и во втором, при снятие со счета, вызывается метод DoEvent(Bank b) класса SecurytyMonitor, в который передается объект класса Bank, с помощью которого, мы доступаемся к событию OnStop класса Bank, и подписываем его на метод Display() класса SecurytyMonitor.
Вот клиентская часть Main():
using System;
namespace UseEvent
{
/// <summary>
/// класс в котором определена точка входа в программу
/// </summary>
class Program
{
/// <summary>
/// точка входа в програму
/// </summary>
static void Main()
{
// создаем счет в банке
Bank myBank = new Bank(1, -10);
myBank.Show(); // выводим
// создаем счет в банке
Bank myBank2 = new Bank(2, 199);
myBank2.Show(); // выводим
// пробуем снять больше чем возможно
myBank2.TakeOfMony(200);
// задержываем екран
Console.ReadLine();
}
}
}

В коде написаны тройные комментарии, с помощью которых мы можем спокойно с помощью Visual Studio просмотреть в виде документации. Для этого едем в пункт меню View->Object Browser:


Возможно, пример с банком не самый удачный способ показать события, но суть не в банке. Суть в самом использование делегатов используемых события!
Вторая часть Использование делегатов в событиях на c#