Чтение онлайн

ЖАНРЫ

C# 4.0 полное руководство - 2011

Шилдт Герберт

Шрифт:

Групповое преобразование делегируемых методов

Еще в версии C# 2.0 было внедрено специальное средство, существенно упрощающее синтаксис присваивания метода делегату. Это так называемое групповое преобразование методов, позволяющее присвоить имя метода делегату, не прибегая к оператору new или явному вызову конструктора делегата.

Ниже приведен метод Main из предыдущего примера, измененный с целью продемонстрировать групповое преобразование методов.

static void Main {

//

Сконструировать делегат, используя групповое преобразование методов. StrMod strOp = ReplaceSpaces; // использовать групповое преобразование методов string str;

// Вызвать методы с помощью делегата, str = strOp("Это простой тест.");

Console.WriteLine("Результирующая строка: " + str);

Console.WriteLine;

strOp = RemoveSpaces; // использовать групповое преобразование методов str = strOp("Это простой тест.");

Console.WriteLine("Результирующая строка: " + str);

Console.WriteLine ;

strOp -= Reverse; // использовать групповое преобразование методов str = strOp("Это простой тест.");

Console.WriteLine("Результирующая строка: " + str);

Console.WriteLine ;

}

Обратите особое внимание на то, как создается экземпляр делегата strOp и как ему присваивается метод Rep la се Spaces в следующей строке кода.

strOp = RemoveSpaces; // использовать групповое преобразование методов

В этой строке кода имя метода присваивается непосредственно экземпляру делегата strOp, а все заботы по автоматическому преобразованию метода в тип делегата "возлагаются" на средства С#. Этот синтаксис может быть распространен на любую ситуацию, в которой метод присваивается или преобразуется в тип делегата.

Синтаксис группового преобразования методов существенно упрощен по сравнению с прежним подходом к делегированию, поэтому в остальной части книги используется именно он.

Применение методов экземпляра в качестве делегатов

В предыдущем примере использовались статические методы, но делегат может ссылаться и на методы экземпляра, хотя для этого требуется ссылка на объект. Так, ниже приведен измененный вариант предыдущего примера, в котором операции со строками инкапсулируются в классе StringOps. Следует заметить, что в данном случае может быть также использован синтаксис группового преобразования методов.

// Делегаты могут ссылаться и на методы экземпляра.

using System;

// Объявить тип делегата, delegate string StrMod(string str);

class StringOps {

// Заменить пробелы дефисами.

public string ReplaceSpaces(string s) {

Console.WriteLine("Замена пробелов дефисами."); return s.Replace(' '-');

}

// Удалить

пробелы.

public string RemoveSpaces(string s) { string temp = ""; int i;

Console.WriteLine("Удаление пробелов."); for(i=0; i < s.Length; i++) if(s[i] != ' ') temp += s[i ] ;

return temp;

}

// Обратить строку, public string Reverse(string s) { string temp = ""; int i, j;

Console.WriteLine("Обращение строки."); for(j=0, i=s.Length-1; i >= 0; i—, j++) temp += s[i];

return temp;

}

}

class DelegateTest { static void Main {

StringOps so = new StringOpsO; // создать экземпляр

// объекта класса StringOps

// Инициализировать делегат.

StrMod strOp = so.ReplaceSpaces; string str;

// Вызвать методы с помощью делегатов, str = strOp("Это простой тест.");

Console.WriteLine("Результирующая строка: " + str);

Console.WriteLine;

strOp = so.RemoveSpaces;

str = strOp("Это простой тест.");

Console.WriteLine("Результирующая строка: " + str);

Console.WriteLine;

strOp = so.Reverse;

str = strOp("Это простой тест.");

Console.WriteLine("Результирующая строка: " + str);

}

}

Результат выполнения этого кода получается таким же, как и в предыдущем примере, но на этот раз делегат обращается к методам по ссылке на экземпляр объекта класса StringOps.

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

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

Ниже приведен пример групповой адресации. Это переработанный вариант предыдущих примеров, в котором тип значений, возвращаемых методами манипулирования строками, изменен на void, а для возврата измененной строки в вызывающую часть кода служит параметр типа ref. Благодаря этому методы оказываются более приспособленными для групповой адресации.

// Продемонстрировать групповую адресацию.

using System;

// Объявить тип делегата.

Поделиться с друзьями: