Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теоретический_курс.doc
Скачиваний:
36
Добавлен:
10.11.2019
Размер:
7.68 Mб
Скачать

6. Групповая адресация

Одним из самых примечательных свойств делегата является поддержка групповой адресации. Попросту говоря, групповая адресация — это возможность создать список, или цепочку вызовов, для методов, которые вызываются автоматически при обращении к делегату. Создать такую цепочку нетрудно. Для этого достаточно получить экземпляр делегата, а затем добавить методы в цепочку с помощью оператора (+) или (+=). Для удаления метода из цепочки служит оператор (-) или (-=). Если делегат возвращает значение, то им становится значение, возвращаемое последним методом в списке вызовов. Поэтому делегат, в котором используется групповая адресация, обычно имеет возвращаемый тип void. Пример:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LC_Console

{

delegate void OpStroke(ref int[] arr);

public class ArrOperation

{

public static void WriteArray(ref int[] arr)

{

Console.WriteLine("Исходный массив: ");

foreach (int i in arr)

Console.Write("{0}\t", i);

Console.WriteLine();

}

// Сортировка массива

public static void IncSort(ref int[] arr)

{

int j, k;

for (int i = 0; i < arr.Length - 1; i++)

{

j = 0;

do

{

if (arr[j] > arr[j + 1])

{

k = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = k;

}

j++;

}

while (j < arr.Length - 1);

}

Console.WriteLine("Отсортированный массив в большую сторону: ");

foreach (int i in arr)

Console.Write("{0}\t", i);

Console.WriteLine();

}

public static void DecSort(ref int[] arr)

{

int j, k;

for (int i = 0; i < arr.Length - 1; i++)

{

j = 0;

do

{

if (arr[j] < arr[j + 1])

{

k = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = k;

}

j++;

}

while (j < arr.Length - 1);

}

Console.WriteLine("Отсортированный массив в меньшую сторону: ");

foreach (int i in arr)

Console.Write("{0}\t", i);

Console.WriteLine();

}

// Заменяем нечетные числа четными и наоборот

public static void ChetArr(ref int[] arr)

{

Console.WriteLine("Чётный массив: ");

for (int i = 0; i < arr.Length; i++)

if (arr[i] % 2 != 0)

arr[i] += 1;

foreach (int i in arr)

Console.Write("{0}\t", i);

Console.WriteLine();

}

public static void NeChetArr(ref int[] arr)

{

Console.WriteLine("Нечётный массив: ");

for (int i = 0; i < arr.Length; i++)

if (arr[i] % 2 == 0)

arr[i] += 1;

foreach (int i in arr)

Console.Write("{0}\t", i);

Console.WriteLine();

}

}

class Program

{

static void Main()

{

int[] myArr = new int[6] { 2, -4, 10, 5, -6, 9 };

// Структуируем делегаты

OpStroke Del;

OpStroke Wr = ArrOperation.WriteArray;

OpStroke OnSortArr = ArrOperation.IncSort;

OpStroke OffSortArr = ArrOperation.DecSort;

OpStroke ChArr = ArrOperation.ChetArr;

OpStroke NeChArr = ArrOperation.NeChetArr;

// Групповая адресация

Del = Wr;

Del += OnSortArr;

Del += ChArr;

Del += OffSortArr;

Del += NeChArr;

// Выполняем делегат

Del(ref myArr);

Console.WriteLine("Для продолжения нажмите любую клавишу . . .");

Console.ReadKey();

}

}

}

Рис. 6. 1. Результат работы кода выше

Цепочки вызовов являются весьма эффективным механизмом, поскольку они позволяют определить ряд методов, выполняемых единым блоком. Благодаря этому улучшается структура некоторых видов кода. Кроме того, цепочки вызовов имеют особое значение для обработки событий.