c # универсальный делегат без параметра - определите и вызовите - PullRequest
5 голосов
/ 25 июля 2011

В настоящее время я выполняю рефакторинг существующего DAL, который имеет фасад, который вызывает пользователь, и внутренний класс, который выполняет фактическую работу, зависящую от использования ADO.Net, например, для использования. SqlProvider, и я пытаюсь убедиться, что код СУХОЙ, я все сделал хорошо, используя Func, поэтому я могу сделать:

return RunCommand(c => c.ExecuteNonQuery(commandText, parameters));

И метод RunCommand выглядит так:

    private T RunCommand<T>(Func<Commands, T> toRun)
    {
        return toRun(CreateCommand());
    }

Метод CreateCommand() просто создает объект команды для использования, что позволяет мне иметь единственный метод, который обрабатывает все вызовы, которые просто возвращают ожидаемый тип, например. DataSet, DataReader и т. Д.

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

 Commands commands = CreateCommand();
 return commands.ExecuteNonQuery(out cmd, commandText, parameters);

Что я действительно хотел бы сделать, так это уметь звонить:

return RunCommand(c => c.ExecuteNonQuery(out cmd, commandText, parameters));

Я видел этот существующий вопрос, но я не могу понять, как превратить это в то, что мне нужно.

Казалось бы, этот делегат мне нужен private delegate V TestOutParameter<T, U, V>(T a, out U b, V c);, но код, который я получил для его вызова, просто неверен:

    private V RunCommand<T, U, V>(TestOutParameter<Commands, DbCommand, V> commandToExecute)
    {
        DbCommand cmd;
        return (V)commandToExecute(CreateCommand(), out cmd);
    }

Кто-нибудь может мне помочь, так как это сводит меня с ума в течение недели!

1 Ответ

11 голосов
/ 25 июля 2011

Ваш делегат имеет три параметра вместо двух. Предполагая, что вы хотите, чтобы оно отражало Func, вместо:

private delegate V TestOutParameter<T, U, V>(T a, out U b, V c);

вы должны иметь:

private delegate V TestOutParameter<T, U, V>(T a, out U b);

Я бы лично порекомендовал вам переименовать его в что-то вроде:

private delegate TResult FuncOut<T1, T2, TResult>(T1 arg1, out T2 arg2)
...