Если вы еще не готовы погружаться в глубины функционального программирования (возможности которого замечательно описаны здесь) или просто ищете максимально простой способ передать одну функцию в виде аргумента в другую функцию, вам идеально подойдет делегат 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> или написать свой собственный.
_someClassObject.ExecuteWithDbCommand(someDatabaseFunction);
а как же параметры функции someDatabaseFunction ??
Вот что мне было нужно. Спасибо!!!
Нужен недорогой магазин женской одежды, напишите кому не лень сылки.
Думать вредно, от этого настроение портиться.