1) Сначала вы должны понять, почему / когда вам нужен делегат, в чем заключается проблема, которую он решает.
По своему опыту я в основном использую их, чтобы позволял пользователю настраивать поведение объекта .
Представьте себе Grid компонент, который позволяет разработчику настраивать отображение каждого столбца.
Например, вы хотите написать значение красного цвета, когда число меньше нуля.
Разработчик, создавший Grid, не знает, как пользователь хочет настроить вывод, поэтому ему нужен механизм, позволяющий пользователю компонента внедрить некоторую логику в компонент .
2) Тогда вы должны понять, как работает делегат
Что сбивает с толку, так это странный код, который вы должны написать для этого, и многими способами вы должны сделать то же самое.
Это класс сетки:
// the grid let the programmer that will use it to customize the output
public class Grid{
// 1) First I declare only the interface of the delegate
public delegate String ValueFormatterDelegate(String v);
// 2) I declare a handler of the implementation of the delegate
public ValueFormatterDelegate ValueFormatterHandler;
// 3) I call the handler inside the Print method
public void Print(String x){
Console.WriteLine( ValueFormatterHandler.Invoke(x) );
}
}
// 1) Сначала я объявляю только интерфейс делегата
открытый делегат String ValueFormatterDelegate (String v);
Обратите внимание, что это похоже на обычный метод, но:
- имеет делегат ключевое слово
- не имеет реализации
Таким образом я говорю: «метод, который будет форматировать выходные данные, имеет такой интерфейс: он будет принимать строку в качестве входных данных и будет выводить строку»
Это помните мне определение метода интерфейса.
// 2) Я объявляю обработчик реализации делегата
public ValueFormatterDelegate ValueFormatterHandler;
Теперь мне нужно создать свойство типа делегата, которое будет обрабатывать реализацию этого метода.
// 3) я вызываю обработчик внутри метода Print
public void Print (Строка x) {
Console.WriteLine (ValueFormatterHandler.Invoke (x));
}
Внутри метода Print я могу использовать обработчик, который свяжет реальную реализацию.
ValueFormatterHandler имеет тип ValueFormatterDelegate
и ValueFormatterDelegate является делегатом рекламы
и .Invoke - метод типа делегата
Это программа, использующая мой класс Grid и способная персонализировать его на лету.
Проблема в том, что вам нужно делать одно и то же.
using System;
public class Program{
public static void Main(){
var printer = new Printer();
// METHOD 1 : link to a named method
// here i link the handler of the delegate to a real method
// the FormatXXX is a static method defined at the ed of this code
printer.ValueFormatter = FormatXXX;
// when i call Print("hello")
printer.Print("hello"); // XXhelloXX
// METHOD 2 : anonimous method
// think at this like a method but without a name
// FormatYY (String x ){ return "YY"+x+"YY"; };
// become
// delegate (String x ){ return "YY"+x+"YY"; };
printer.ValueFormatter = delegate (String x ){ return "YY"+x+"YY"; };
printer.Print("hello"); // YYhelloYY
// METHOD 3 : anonimous method using lambda
// as you can note the type of parameter x is inferred from the delegate declaration
// public delegate String ValueFormatterDelegate(String v);
printer.ValueFormatter = (x)=>"KK" + x + "KK";
}
public static String FormatXXX(String y){
return "XX"+ y +"XX";
}
}