I`m having some trouble in understanding how delegates in C# work. I have many code examples, but i still could not grasp it properly.
Can someone explain it to me i
1) First you have to understand why/when you need a delegate, what is the problem that it solve.
In my experience I mainly use them to allow a user to customize an object's behavior.
Immagine a Grid component that allows the developer to customize how each column will be rendered. For example you want to write a of red color value when it's a number under zero.
The developer that create the Grid does not know how the user want to customize the output so it need a mechanism that let the user of the component to inject some logic into the component.
2) Then you have to understand how the delegate works
What is confusing is the strange code you have to write to do so, and the many ways you have to do the same thing.
This is the grid class:
// 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) First I declare only the interface of the delegate public delegate String ValueFormatterDelegate(String v);
Note that is like a normal method but:
In this way I say: "the method that will format the output has this interface: it will take a string as input and it will output a string"
It remember to me a definition of a method of an interface.
// 2) I declare a handler of the implementation of the delegate public ValueFormatterDelegate ValueFormatterHandler;
Now I have to create a property of the type of the delegate that will handle te implementation of this method.
// 3) I call the handler inside the Print method public void Print(String x){ Console.WriteLine( ValueFormatterHandler.Invoke(x) ); }
Inside the Print method I can use the handler that will link the real implementation.
ValueFormatterHandler is of type ValueFormatterDelegate and ValueFormatterDelegate is ad delegate and .Invoke is a method of delegate type
This is a program that use my Grid class and is able to personalize it on the fly. The problem here is the many ways you have to do the same thing.
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";
}
}