Новинки языка C#.NET - Безымянные методы

ОГЛАВЛЕНИЕ

 

Безымянные методы

Безымянные методы (anonymous methods) позволяют значительно сократить объем кода, который должен написать разработчик. Наиболее простое и понятное использование безымянных методов при назначении относительно простых обработчиков событий. Рассмотрим пример, пусть у нас есть форма, на которой размещены текстовое поле txtLogin и кнопка btnLoginи нам нужно, чтобы при изменении текста в текстовом поле, изменялся текст кнопки. Разумеется, что для этого необходимо в обработчике события TextChanged изменять текст кнопки.

Какой код создает Visual Studio при добавлении нового обработчика события? Прежде всего функцию обработчик и запись о соответствии функции обработчика событию, что осуществляется присвоением соответствующего делегата соответствующему событию контрола TextBoxв функции InitializeComponent:

this.txtLogin.TextChanged += new System.EventHandler(this.txtLogin_TextChanged);

Сам обработчик выглядит так:

private void txtLogin_TextChanged(object sender, EventArgs e)
{
btnLogin.Text = "Login [" + txtLogin.Text + "]";
}

Те же операции можно выполнить вручную создав, например, такой код:

public frmMain()
{
InitializeComponent();
this.txtLogin.TextChanged += new System.EventHandler(this.txtLogin_TextChanged);
}
private void txtLogin_TextChanged(object sender, EventArgs e)
{
btnLogin.Text = "Login [" + txtLogin.Text + "]";
}

Теперь же перепишем этот код с использованием безымянных методов:

public frmMain()
{
InitializeComponent();
this.txtLogin.TextChanged += delegate { btnLogin.Text = "Login [" + txtLogin.Text + "]"; };
}

Таким образом мы поместили код обработчика непосредственно в место присваивания делегата событию TextChanged. Формально этот процесс ничего не меняет - в момент  компиляции компилятор сам создаст функцию и присвоит ей некоторое имя, а потом создаст делегат для этой функции и присвоит его событию TextChanged. Но отметьте, на сколько меньше строк кода нужно для реализации, при этом никаких потерь производительности после компиляции не будет, поскольку в результате будет получен такой же код, что и в примерах описанных выше.

Конечно, приведенный пример практической ценности не имеет (а если и имеет, но весьма и весьма небольшую), но демонстрирует общий путь использования безымянных методов. При этом ничто не мешает получить доступ к передаваемым функции параметрам, для этого нужно лишь явно указать их при написании безымянного метода:

this.btnLogin.Click += delegate(object sender, EventArgs e) 
{MessageBox.Show(((Button)sender).Text.ToString());};

В дополнение приведу более общий пример использования безымянных методов:

public delegate int MyDelegate(int mInt1, int mInt2);
private void btnAnonymous_Click(object sender, EventArgs e)
{
MyDelegate anSum = delegate(int a, int b) { return a + b; };
MessageBox.Show(anSum(1, 2).ToString());
}

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