static void Inform(string name) // Этот метод является будущим заданием делегата
{
Console.WriteLine(Environment.ExpandEnvironmentVariables(name));
}
Добавьте в Main код вызова метода Inform с помощью generic-делегата Action<string> и выполните код.
Action<string> s = Inform;
s("%SystemDrive%");
¨ Шаблон Action<T> делегата s настроен на сигнатуру void (string).
¨ Обращение к делегату: s ("%SystemDrive%"); эквивалентно вызову Inform ("%SystemDrive%");.
Следующая версия шаблона Action<> позволяет создавать делегаты, которые способны вызывать функции с двумя параметрами.
public delegate void Action<T1, T2> (T1 arg1, T2 arg2);
Типы параметров настраиваются с помощью параметров шаблона T1 и T2. Рассмотрим пример. Добавьте в класс Program метод SaveImage, сигнатура которого соответствует типу Action<string, byte[]>.
static void SaveImage(string file, byte[] data)
{
File.WriteAllBytes(file, data);
}
Добавьте в Main код вызова метода SaveImage с помощью generic-делегата типа Action<string, byte[]>.
byte[] img = File.ReadAllBytes(@"C:\WINDOWS\Web\Wallpaper\Windows XP.jpg");
Action<string, byte[]> save = SaveImage;
save(@"C:\Test.jpg", img);
Библиотека System.Core.dll содержит определение еще двух делегатных типов из семейства Action<>. Они соответствуют void-методам с тремя и четырьмя параметрами. Типы параметров, как и ранее, задаются с помощью параметров шаблона. Семейство шаблонов Action<> позволяет создавать делегаты для вызова void-методов, имеющих от 0 до 4 параметров. Этот шаблон охватывает довольно широкий класс методов, которые могут встретиться на практике.
В System.Core.dll также определено семейство делегатных типов Func<>, которое соответствует произвольным методам, возвращающим значение произвольного типа. Как и в случае с Action<>, существует несколько объявлений этого делегатного типа. Они отличаются количеством входных параметров (от одного, до четырех). Рассмотрим объявление этого делегатного типа для функций с одним параметром.
public delegate TResult Func <T,TResult> (T arg);
Указанное объявление generic-делегата сообщает программисту и компилятору о том, что Func является типом указателей, способных адресовать любую функцию, которая на входе требует переменную типа T и возвращает переменную типа TResult. Как видите, последний (второй) параметр шаблона (TResult) определяет тип возвращаемого функцией значения, а первый — тип входного параметра функции.
При объявлении делегата (указателя) программист задает конкретные типы (T и TResult), после чего компилятор настраивает шаблон на эти типы, то есть, генерирует делегат (код вызова метода). Имея делегатный тип (сигнатуру делегата), можно определить новый делегат (указатель), например так:
Func<double, double> pFunc = Math.Sin; // pFunc указывает на метод, вычисляющий синус
Console.WriteLine (pFunc(1.5)); // Вызов метода с помощью pFunc. Результат: 0,997494986604054
pFunc = Math.Sqrt; // Теперь pFunc указывает на метод, вычисляющий квадратный корень
Console.WriteLine (pFunc(1.5)); // Результат: 1,22474487139159
Указателю pFunc можно присвоить имя (вы помните, что имя — это адрес) функции Sin или функции Sqrt. Указателю можно присвоить имя (адрес) любой другой функции с сигнатурой double (double).
Делегатный тип Func описывает любую функцию с одним параметром типа T, которая возвращает переменную типа TResult. С помощью делегата Func <Person, int> p, настроенного на типы Person и int, можно вызвать несколько разных методов, например: int GetHash (Person), или int GetPersonID (Person).
В пространстве имен System определены еще несколько делегатных типов вида Func<>. Например.
delegate TResult Func <T, U, TResult> (T a, U b);
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.