Использование делегата: бизнес-приложения

Если вы хотите сделать что-то умное / злое, вы можете использовать ключевое слово when, чтобы ввести ведение журнала без прерывания трассировки стека в вашем исключении.

См. , когда контекстное ключевое слово в ссылке C # на MSDN. Предполагается, что он будет использоваться в качестве фильтра (метод возвращает значение true или false, указывающее, следует ли использовать этот блок catch), но вы можете делать все, что захотите, с помощью

Я думаю, что это то, что вы хотите, хотя Я не проверял это:

public void someFunction(object data)
{
    try 
    {
        var response = await request(data);
        LogInformation(request: data, response: response);
    }
    catch (Exception e) when (HandleAndLogException(data, e))
    {
         throw;
    }
}

private bool HandleAndLogException(object data, Exception e)
{
    LogException(data: data, response: e.Message);
    return true;
}

5
задан Community 23 May 2017 в 10:27
поделиться

8 ответов

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

Вот один контекст, в котором я недавно использовал делегатов (форматирование и имена, изменившие в целях презентации:)

protected T[] SortLines<T>(Func<T> createLine, IEnumerable<T> unsorted)
where T : LineType
{
    Func<IEnumerable<T>, IEnumerable<T>> sorter = (lines => lines);

    switch (settings.OrderSort)
    {
        case OrderSort.ByA: 
            sorter = (lines => lines.OrderBy(x => x.A)); break;
        case OrderSort.ByB:
            sorter = (lines => lines.OrderBy(x => x.B)); break;

        // and so on... a couple cases have several levels of ordering
    }

    bool requiresSplit = // a complicated condition
    if (requiresSplit)
    {
        var positives = unsorted.Where(x => x.Qty >= 0);
        var negatives = unsorted.Where(x => x.Qty <  0);

        return sorter(negatives).Concat(
               new T[] { createLine.Invoke() }).Concat(
               sorter(positives)).ToArray();
    }
    else
        return sorter(unsorted).ToArray();
}

Таким образом, это сортирует группу объектов на основе некоторых критериев и затем этого или возвращает целый список, отсортированный, или это повреждает его в два, виды обе половины отдельно, и помещает разделитель, промежуточный их. Удача, делающая это изящно, если Вы не можете выразить понятия "способа отсортировать что-то", которое является тем, для чего делегат.

Править: Я предполагаю Concat, и OrderBy конкретны для 3.0, но это - все еще основная идея.

4
ответ дан 18 December 2019 в 13:19
поделиться

Кроме GUI...

  1. диспетчеризация события; некоторые мои бизнес-приложения являются вполне сложными, говорят с устройствами и полагаются на очереди событий для хранения всего в синхронизации. Делегаты используются этими приложениями для диспетчеризации события.
  2. бизнес-правила; некоторые мои бизнес-приложения имеют частичную мягко кодирующую способность, где определенные события инициировали определенные правила, которые сохранены в базе данных. Делегаты (в Словаре) используются для выполнения правил о клиентском. (Плагины могли поддерживаться, но текущий не нужны).
  3. общие вторичные потоки (использующий класс SafeThread, конечно!)
2
ответ дан 18 December 2019 в 13:19
поделиться

К моему знанию делегат.NET является по существу реализацией интерфейса отдельного метода без всей шумихи объявления класса. Мне жаль, что у нас не было их в Java, лично. Думайте о классе компаратора:

class MyComparator<Circle> extends Comparator<Circle> {
    public int compare(Circle a, Circle b) {
        return a.radius - b.radius;
    }
}

Везде этот шаблон полезен, делегат мог быть полезным вместо этого.

Я надеюсь, что я прав, но разрешение и проваливает меня, если я неправ; это было слишком длинно, так как я видел любой C# :)

2
ответ дан 18 December 2019 в 13:19
поделиться

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

enum State {
  Loading,
  Processing,
  Waiting,
  Invalid
}

delegate void StateFunc();

public class StateMachine  {
  StateFunc[] funcs;   // These would be initialized through a constructor or mutator
  State curState;

  public void SwitchState(State state)  {
    curState = state;
  }

  public void RunState()  {
    funcs[curState]();
  }
}

Мои 2,0 синтаксиса делегата могут быть ржавыми, но это - довольно простой пример диспетчера состояния. Также помните, что делегаты в C# могут выполнить больше чем одну функцию, позволив Вам иметь конечный автомат, который выполняет произвольно много функций каждый RunState ().

2
ответ дан 18 December 2019 в 13:19
поделиться

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

1
ответ дан 18 December 2019 в 13:19
поделиться

Делегаты становятся чрезвычайно мощными, когда Вы начинаете смотреть на них как на функциональные конструкции

.Net 2.0 включал поддержку анонимных делегатов, которые сформировали ядро некоторых функциональных понятий, на которых подробно остановился Linq. Синтаксис для анонимного делегата является немного более большим, чем, какое предложение Лямбды, но много базовых функциональных шаблонов находится там в 2,0.

В Списке универсальный тип у Вас есть следующие объекты, с которыми можно работать:

  1. ConvertAll () - Использование делегат для преобразования всех членов списка в другой тип (T). Это - в основном реализация Функции Карты
  2. Найдите (), и FindAll, оба берут делегатов и возвратят Вас любой единственный объект (в случае Находки ()), или все объекты, которые вызывают делегата, передали в оценить к истинному. Это обеспечивает функцию Фильтра и также определение Предиката (функция, которая оценивает к булевской переменной),
  3. Существует реализация ForEach () метод, который берет делегата. Разрешение Вам выполнить произвольную операцию против каждого элемента в списке.

Appart из Списка определенные объекты, когда Ваш использующий анонимный контекст делегатов обрабатывается правильно, таким образом, можно реализовать Закрытие как структуры. Или, на большем practicle уровне делают что-то как:

ILog logger = new Logger();
MyItemICareAbout.Changed += delegate(myItem) { logger.Log(myItem.CurrentValue); };    

И это просто работает.

Существует также материал DynamicMethod, который позволяет Вам определять биты IL (использующий Отражение. Испустите), и скомпилируйте их как делегатов. Это дает Вам хорошую альтернативу чистому отражению для вещей как Отображающиеся слои и код доступа к данным.

Делегаты являются действительно конструкцией, которая позволяет Вам представлять исполняемый код как данные. После того как Вы получаете голову вокруг того, что это означает, существует много вещей, которые могут быть сделаны. Поддержка этих конструкций в 2,0 была элементарной по сравнению с 3,5, но все еще там, и все еще довольно мощной.

1
ответ дан 18 December 2019 в 13:19
поделиться

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

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

1
ответ дан 18 December 2019 в 13:19
поделиться

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

some_condition = setup_logic
...
while (not terminated) {
    data = obtain_data
    if (some_condition)
        process_one (data)
    else
        process_two (data)
}

Дело в том, что, если some_condition не изменяется на основе ничего в цикле, затем нет действительно никакого преимущества от повторного тестирования его. Делегаты/закрытия/и т.д. позвольте вышеупомянутому быть замененным этим:

some_condition = setup_logic
if (some_condition)
    selected_process = process_one
else
    selected_process = process_two
...
while (not terminated) {
    data = obtain_data
    selected_process (data)
}

(Конечно, Настоящий Функциональный Программист записал бы установку как:

selected_process = if (some_condition) process_one else process_two

;-)

Это делает вывод приятно к нескольким альтернативам (вместо всего два). Ключевая идея состоит в том, чтобы решить заранее, какие меры принять в моменте в будущем (или точки) и затем помнить выбранное действие, а не значение, на котором базировалось решение.

1
ответ дан 18 December 2019 в 13:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: