Делегат - это простой контейнер, который знает, где в памяти машины находится определенный метод.
У всех делегатов есть метод Invoke(...)
, поэтому, когда у кого-то есть делегат, он может его выполнить, не имея необходимости знать или беспокоиться о том, что на самом деле делает этот метод.
Это особенно полезно для разделения вещей. Каркасы GUI были бы невозможны без этой концепции, потому что Button
просто не может ничего знать о вашей программе, в которой вы собираетесь ее использовать, поэтому он не может сам вызывать ваши методы при каждом нажатии. Вместо этого вы должны указать ему, какие методы он должен вызывать при нажатии.
Полагаю, вы знакомы с событиями и регулярно ими пользуетесь. Поле event
на самом деле представляет собой список таких делегатов (также называемый многоадресным делегатом). Возможно, все станет яснее, когда мы посмотрим, как мы могли бы «симулировать» события в C #, если бы в нем не было ключевого слова event
, а были только (не многоадресные) делегаты:
public class Button : Rectangle
{
private List<Delegate> _delegatesToNotifyForClick = new List<Delegate>();
public void PleaseNotifyMeWhenClicked(Delegate d)
{
this._delegatesToNotifyForClick.Add(d);
}
// ...
protected void GuiEngineToldMeSomeoneClickedMouseButtonInsideOfMyRectangle()
{
foreach (Delegate d in this._delegatesToNotifyForClick)
{
d.Invoke(this, this._someArgument);
}
}
}
// Then use that button in your form
public class MyForm : Form
{
public MyForm()
{
Button myButton = new Button();
myButton.PleaseNotifyMeWhenClicked(new Delegate(this.ShowMessage));
}
private void ShowMessage()
{
MessageBox.Show("I know that the button was clicked! :))))");
}
}
Надеюсь, я смогу немного помочь. ; -)