Не получается избежать копи-паста. Нужно что-то типа макросов
От: J-son  
Дата: 01.05.18 14:24
Оценка:
Здравствуйте, есть такой вопрос:

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

class ExtWebAPI
{
    public AParam GetParameter(string aSerialNumber, string aParameterName)
        {
            AParam ap = null;

            int count = 0;
            while (++count < _RetriesCount)
            {
                try
                {
                    ap = _Main.GetParameter(aSerialNumber, aParameterName);
                    break;
                }
                catch (Exception)
                {
                    ExceptionHandling();
                }
            }

            return ap;
        }


        public AResult OperationStart(string aSerialNumber, string PartNumber, string aOperationCode)
        {
            AResult ar = null;

            int count = 0;
            while (++count < _RetriesCount)
            {
                try
                {
                    ar = _Main.OperationStart(aSerialNumber, PartNumber, aOperationCode);
                    break;
                }
                catch (Exception)
                {
                    ExceptionHandling();
                }
            }

            return ar;
        }
}


То есть, некая функция Веб-Сервиса пытается выполниться, если неудачно, то происходит переключение между серверами и происходит повторение.

Вопрос такой:
У меня в проекте таких функций около 50 штук и выглядят они посложнее (тут просто упростил). Но видно, что все обертки по сути делают одно и то же — вызывают в цикле другую функцию.
Поэтому, хотелось бы как-то уменьшить объем кода.
Сюда просится какая-то функция, которая бы брала другую функцию как аргумент. Но сигнатуры у всех совершенно разные. Такой вариант не подходит.
Или какой-нибудь макрос, как в C++, но в C# их нет.
Есть ли какой-то способ?

Заранее спасибо.
Re: Не получается избежать копи-паста. Нужно что-то типа мак
От: GarryIV  
Дата: 01.05.18 14:44
Оценка: 1 (1)
Здравствуйте, J-son, Вы писали:

JS>Здравствуйте, есть такой вопрос:


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


Макрос не нужен тебе, паттерн команда используй. Вызов оформи в виде команды, пареметры передаются внутрь при создании команды. Дальше дело техники.

Я практически 146% уверен, что это все есть в либах хороших. Даже если не захочешь брать просто посмотри как другие делают.
WBR, Igor Evgrafov
Отредактировано 01.05.2018 14:46 GarryIV . Предыдущая версия . Еще …
Отредактировано 01.05.2018 14:44 GarryIV . Предыдущая версия .
Re: Не получается избежать копи-паста. Нужно что-то типа мак
От: bnk СССР http://unmanagedvisio.com/
Дата: 01.05.18 14:55
Оценка: 13 (3) +1
Здравствуйте, J-son, Вы писали:

JS>Есть ли какой-то способ?


Лямбда?

class ExtWebAPI
{
    public R Execute<R>(Func<R> f)
    {
            R r = default(R);

            int count = 0;
            while (++count < _RetriesCount)
            {
                try
                {
                    r = f();
                    break;
                }
                catch (Exception)
                {
                    ExceptionHandling();
                }
            }

            return r;
    }

    public AParam GetParameter(string aSerialNumber, string aParameterName)
    {
        return Execute(() => _Main.GetParameter(aSerialNumber, aParameterName));
    }


    public AResult OperationStart(string aSerialNumber, string PartNumber, string aOperationCode)
    {
        return Execute(() => _Main.OperationStart(aSerialNumber, PartNumber, aOperationCode));
    }
}
Отредактировано 01.05.2018 14:56 bnk . Предыдущая версия .
Re[2]: Не получается избежать копи-паста. Нужно что-то типа
От: J-son  
Дата: 01.05.18 17:06
Оценка:
Работает!
Я вот одного не пойму (я такой вариант тоже прорабатывал)
Func — это делегат для функций без параметра, а у меня то все с параметрами!
Как это работает тогда?
Отредактировано 01.05.2018 17:08 J-son . Предыдущая версия .
Re[3]: Не получается избежать копи-паста. Нужно что-то типа
От: bnk СССР http://unmanagedvisio.com/
Дата: 01.05.18 18:41
Оценка: 3 (1)
Здравствуйте, J-son, Вы писали:

JS>Работает!

JS>Я вот одного не пойму (я такой вариант тоже прорабатывал)
JS>Func — это делегат для функций без параметра, а у меня то все с параметрами!

Почему без параметра? У Func<> могут быть параметры.. Вроде единственное отличие от Action — то что есть возвращаемое значение. Первым оно же собственно и идет.
Но не суть. В примере же функция без параметров, но с возвращаемым значением.
То есть, кусок кода ниже можно "интерпретировать" как функцию без параметров, но с возвращаемым значением.

() => _Main.OperationStart(aSerialNumber, PartNumber, aOperationCode)

То есть, про aSerialNumber, PartNumber, aOperationCode — можно думать не как про параметры, а скорее как про "захватываемые" значения.
Другими словами, здесь создается безымянная локальная функция без параметров.
Re[3]: Не получается избежать копи-паста. Нужно что-то типа
От: GarryIV  
Дата: 01.05.18 21:39
Оценка: +1
Здравствуйте, J-son, Вы писали:

JS>Работает!

JS>Я вот одного не пойму (я такой вариант тоже прорабатывал)
JS>Func — это делегат для функций без параметра, а у меня то все с параметрами!
JS>Как это работает тогда?

Как работает bnk пояснил, хочу только добавить что это как раз и есть те команды о которых я говорил
WBR, Igor Evgrafov
Re: Не получается избежать копи-паста. Нужно что-то типа макросов
От: Vladek Россия Github
Дата: 03.05.18 07:54
Оценка: +1
Здравствуйте, J-son, Вы писали:

JS>Вопрос такой:

JS>У меня в проекте таких функций около 50 штук и выглядят они посложнее (тут просто упростил). Но видно, что все обертки по сути делают одно и то же — вызывают в цикле другую функцию.
JS>Поэтому, хотелось бы как-то уменьшить объем кода.
JS>Сюда просится какая-то функция, которая бы брала другую функцию как аргумент. Но сигнатуры у всех совершенно разные. Такой вариант не подходит.
JS>Или какой-нибудь макрос, как в C++, но в C# их нет.
JS>Есть ли какой-то способ?

Эту задачу решает библиотека Polly, её применение сократит такой код в разы.
Re[4]: Не получается избежать копи-паста. Нужно что-то типа
От: alexzzzz  
Дата: 03.05.18 12:55
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Почему без параметра? У Func<> могут быть параметры.. Вроде единственное отличие от Action — то что есть возвращаемое значение. Первым оно же собственно и идет.


Не первым. Последним. Сам периодически путался, но сейчас вроде запомнил по принципу: сначала перечисляем типы аргументов на входе, а последним, в конце ― что получится в конце, на выходе.
Re: Не получается избежать копи-паста. Нужно что-то типа макросов
От: IT Россия linq2db.com
Дата: 03.05.18 13:28
Оценка:
Здравствуйте, J-son, Вы писали:

JS>У меня в проекте таких функций около 50 штук и выглядят они посложнее (тут просто упростил). Но видно, что все обертки по сути делают одно и то же — вызывают в цикле другую функцию.


Ещё можно T4 темплейтом нагенерировать.
Если нам не помогут, то мы тоже никого не пощадим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.