Простой способ передать функцию как аргумент в C# - делегат Action<T>

Если вы еще не готовы погружаться в глубины функционального программирования (возможности которого замечательно описаны здесь) или просто ищете максимально простой способ передать одну функцию в виде аргумента в другую функцию, вам идеально подойдет делегат Action<T>.

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

Почему бы не вынести такой кусок кода в еще одну функцию, передаваяя в нее разные функции с участием которых надо выполнить повторяющиеся операции как входной параметр или один из входных параметров? Стандартный подход C# подразумевает создание специального описания этой функции - делегата. Но в простых случаях можно использовать стандартное описание-делегат Action<T>.

Одной из типичных задач C# разработчика является выполнение запросов к базе данных. Чтобы выполнить запрос к базе с помощью OleDb надо как минимум создать и открыть соединение, создать объект команды OleDbCommand. При этом соединение с базой может разорваться в процессе работы и простого способа проверить его состояние нет - то есть надежнее всего заново создавать и открывать/закрывать его каждый раз. Для автоматизации подобной рутины можно написать вот такую функцию с использованием Action<T>

// подразумевается что в свойстве ConnString хранится текстовая строка с параметрами для соединения с базой данных
public void ExecuteWithDbCommand (Action<OleDbCommand> functionToExec)
{
    OleDbConnection dbConn = new OleDbConnection (Database.Instance.ConnString);
    dbConn.Open();
    
    OleDbCommand dbCommand = new OleDbCommand();
    dbCommand.Connection = dbConn;

    functionToExec(dbCommand);

    dbConn.Close();
}

После чего в другом месте мы можем использовать объявить функцию вроде

private void someDatabaseFunction(OleDbCommand dbCommand)
{
    dbCommand.Parameters.Clear();
    dbCommand.CommandText = "delete from SOME_TABLE where SOME_ID = ?";
    dbCommand.Parameters.Add("SOME_ID", OleDbType.Integer).Value = _someIntVariable;
    dbCommand.ExecuteNonQuery();
    
    dbCommand.Parameters.Clear();
    dbCommand.CommandText = "select count(*) from SOME_TABLE";
    _intVariable2 = Convert.ToInt32(dbCommand.ExecuteScalar());
}

И вызвать ее следующим образом

_someClassObject.ExecuteWithDbCommand(someDatabaseFunction);

И повторить это в множестве мест с кучей функций

Делегат Action<T> предзназначен для использования с не возвращающими значений void- функциями и имеет несколько вариантов с разным количеством параметров вплоть до 10. Если надо все-таки вернуть значение, можно использовать стандартный делегат Func<T, TResult> или написать свой собственный.


Комментарии

Простой способ передать функцию как аргумент в C# - делегат Action<T> — Комментарии (5)

  1. _someClassObject.ExecuteWithDbCommand(someDatabaseFunction);

    а как же параметры функции someDatabaseFunction ??

    • Делегат Action предзназначен для использования с не возвращающими значений void- функциями и имеет несколько вариантов с разным количеством параметров вплоть до 10. Если надо все-таки вернуть значение, можно использовать стандартный делегат Func или написать свой собственный.

  2. Нужен недорогой магазин женской одежды, напишите кому не лень сылки.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>