Public class EntryPoint. Public static double StaticCompute(double x, double у)

Public static double StaticCompute(double x, double у)

Public double Compute(double x, double у)

Public class Processor

Одиночный делегат

Создание и использование делегатов

Объявления делегатов выглядят почти так же, как объявления абстрактных методов, за исключением того, что снабжаются одним дополнительным ключевым словом – delegate. Вот как выглядит допустимое объявление делегата:

public delegate double ProcessResults(double x, double у);

Когда компилятор С# встречает эту строку, он определяет тип-наследник MulticastDelegate, который также реализует метод по имени Invoke, имеющий в точности ту же сигнатуру, что и метод, описанный в объявлении делегата. Для практических нужд этот класс выглядит следующим образом:

public class ProcessResults: System.MulticastDelegate

{ public double Invoke(double x, double у);

// Остальное опущено для ясности

}

Несмотря на то, что компилятор создает тип, подобный приведенному, он также абстрагирует использование делегатов за синтаксическими сокращениями. Обычно для вызова делегата применяется синтаксис, подобный вызову функции, а не прямое обращение к методу Invoke. Все это будет показано ниже.

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

В следующем примере показан базовый синтаксис создания делегата.

using System;

public delegate double ProcessResults(double x, double у);

{ public Processor(double factor)

{ this.factor = factor;

}

{ double result = (x + y) * factor;

Console.WriteLine("InstanceResults: {0}", result);

return result;

}

{ double result = (x + y) * 0.5;

Console.WriteLine("StaticResult: {0}", result);

return result;

}

private double factor;

}

{ static void Main()

{ Processor proc1 = new Processor(0.75);

Processor proc2 = new Processor(0.83);

ProcessResults delegate1 = new ProcessResults(proc1.Compute);

ProcessResults delegate2 = new ProcessResults(proc2.Compute);

ProcessResults delegate3 = Processor.StaticCompute;

double combined = delegate1(4, 5) + delegate2(6,2) +

delegate3(5, 2);

Console.WriteLine("Вывод: {0}", combined);

}

}

В приведенном выше примере создаются три делегата. Два из них указывают на методы экземпляра, а один – на статический метод. Обратите внимание, что делегаты создаются посредством создания экземпляров типа ProcessResults, который является типом, созданным объявлением делегата и передачей целевого метода в списке аргументов конструктора. Однако экземпляр delegate3 использует сокращенный синтаксис, когда экземпляру делегата просто присваивается метод. Хотя выглядит так, будто Processor.StaticCompute является именем метода, на самом деле это группа методов, потому что метод может быть перегружен, и это имя может ссылаться на несколько методов. В данном случае группа методов Processor.StaticCompute состоит из одного метода. И чтобы облегчить жизнь, С# позволяет непосредственно присваивать делегату группу методов. При создании экземпляров делегатов с помощью new группа методов передается в конструкторе. Обратите внимание на формат групп методов. В первых двух случаях передается метод экземпляра на экземплярах proc1 и ргос2. Однако в третьем случае передается группа методов типа, а не экземпляра. Подобным образом создается делегат, указывающий на статический метод вместо метода экземпляра. Делегату delegate3 можно было бы также присвоить экземпляр группы методов. В точке вызова делегата синтаксис идентичен и не зависит от того, указывает делегат на метод экземпляра или на статический метод. Конечно, этот пример довольно надуманный, но он дает представление об основах применения делегатов в С#.

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: