Так как обычный метод вызывается для какого-то конкретного объекта класса, то он знает с кем работает и ему нет необходимости передавать ссылку на объект класса. Коды методов Surname и Firstname при этом проще, чем необходимо при вызове статических методов. Статический метод не привязан ни к какому объекту и для того, чтобы он все-таки воздействовал на какой-то конкретный объект, ему надо передать ссылку на него. В связи с этим, нам придется изменить сигнатуру делегата. Замените объявление делегатного типа.
public delegate void ManDelegate (Man m); // Теперь делегатные функции требуют параметр
Подправьте методы Firstname и Surname так, чтобы они работали в статическом варианте.
public static void Firstname (Man m)
{
int n = m.name.IndexOf(' ');
if (n < 0)
n = m.name.Length;
Console.WriteLine(" {0}", m.name.Substring(0, n));
}
public static void Surname(Man m)
{
Console.WriteLine(" {0}", m.name.Substring (m.name.LastIndexOf(' ')+1));
}
Вспомните, что указатель или ссылку, как и любую другую переменную, можно передавать в качестве параметра функции. То же можно делать и с делегатом. Введите в состав класса ManTest метод HandleMen, который будет проходить по всему списку объектов men (типа ArrayList) и выполнять для каждого из них те действия, которые приписаны делегату (читай, статические методы класса Man).
public void HandleMen (string title, ManDelegate func)
{
Console.WriteLine(men.Count == 0 ? "\nList is empty\n" : title);
foreach (Man m in men)
func(m); // Запуск делегатной функции с параметром
}
Обратите внимание на второй парамер функции HandleMen. Он имеет тип делегата (приближенно — указателя на функцию). Если мы вызовем HandleMen и передадим ей в качестве второго параметра делегата, начиненного адресом Firstname, то мы увидим список имен, а если передать делегата, настроенного на функцию Surname, то будут выведены фамилии. Теперь замените обе ветви переключателя в методе Show (мы приведем лишь одну).
case 'f': HandleMen("List of Man Names:", new ManDelegate(Man.Firstname)); break;
Запустите и все должно работать так же как и ранее. Более того, почувствовав уверенностьв делегатной арифметике, мы можем управлять делегатами самым произвольным образом. C помощью операции вычитания можно удалять задания из списка, существующего в данный момент. Например, вы можете опробовать такую версию:
case 'f':
ManDelegate
f = new ManDelegate(Man.Firstname),
s = new ManDelegate(Man.Surname),
d = f + s;
d += f + s;
HandleMen("List of men:", d);
d -= f + s + f; // Корректируем список заданий делегата
HandleMen("List of men:", d); // Вновь просим выполнить все задания
break;
Она выведет пять строк текста для каждого объекта из списка «людей». Четыре — как и в предыдущем случае, а пятую — при запуске скорректированного делегата.
События во всех языках .NET Framework играют весьма важную роль. В концептуальной схеме объектно-ориентированного подхода к разработке систем они используются для реализации функций наблюдателя (observer) — объекта, следящего за изменением состояния каких-то других избранных объектов системы, или, как иногда говорят, объекта «слушающего» сообщения о событиях. Механизм событий настолько прост, что его легко применить для реализации модели наблюдателя.
Событие ассоциируется с сообщением о нем. Объект-источник генерирует сообщение о событии и все зарегистрированные объекты-получатели или слушатели (listeners) получают его. Сообщение может быть создано как операционной системой при наступлении какого-то реального события (нажата кнопка), так и любой программой, когда того требует логика ее алгоритма. В любом случае механизм обработки событий одинаков.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.