Зачем использовать делегатов в .Net

1

Я читал статью, в которой описывалось использование делегатов в следующем примере, который показывает использование делегата многоадресной передачи

 public delegate void ProgressReporter(int percentComplete);
class Program
{
    static void Main(string[] args)
    {
        ProgressReporter p = WriteProgressToConsole;
        p += WriteProgressToFile;
        Utility.HardWork();
    }

    private static void WriteProgressToConsole(int percentComplete)
    {
        Console.WriteLine(percentComplete);
    }

    private static void WriteProgressToFile(int percentComplete)
    {        
        System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());           
    }
}


  public static class Utility
{
    public static void HardWork(ProgressReporter p)
    {
        for (int i = 0; i < 10; i++)
        {     
            p(i);
            System.Threading.Thread.Sleep(1000);
        }
    }
}

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

 public static class ProgressReporter
{
    public static void WriteProgressToConsole(int percentComplete)
    {
        Console.WriteLine(percentComplete);
    }

    public static void WriteProgressToFile(int percentComplete)
    {
        System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());
    }
}

и изменение класса Utility HardWork() следующим образом

 public static class Utility
{
    public static void HardWork()
    {
        for (int i = 0; i < 10; i++)
        {
            ProgressReporter.WriteProgressToConsole(i * 10);
            ProgressReporter.WriteProgressToFile(i * 10);
            System.Threading.Thread.Sleep(1000);
        }
    }
}

Поэтому мой вопрос в отношении этого кода заключается в том, почему нам на самом деле нужен делегат на первом месте?

Некоторые из причин (plz правильно, если я ошибаюсь), которые, я думаю, нам нужен делегат, как follows-

  1. Если нам нужно уведомление в самом классе программы, нам нужны делегаты.
  2. С помощью многоадресного делегата мы можем одновременно вызвать несколько функций вместо вызова их несколько раз (как в моем втором случае).
Теги:
delegates

2 ответа

3
Лучший ответ

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

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

Примеры ситуаций, в которых жесткое кодирование не будет выполняться, а методы интерфейса/переопределения будут более эффективными, чем делегаты, попробуйте посмотреть на визуальные компоненты и их события. События в.NET используют делегаты. Вы можете просто дважды щелкнуть по кнопке в визуальном дизайнере в Visual Studio и создать этот метод для вас и связать его с событием на стороне делегата. Необходимость создания класса или реализации интерфейса поверх класса формы будет намного более эффективной, и особенно если у вас есть несколько кнопок, которые вы хотите делать разными способами, то вам определенно нужно несколько объектов, реализующих эти интерфейсы.

Поэтому делегаты имеют свое место, но ваши примеры не оправдывают их.

Вот пример LINQPad, который демонстрирует, что один метод (DoSomething) может в конечном итоге делать разные вещи в зависимости от предоставленного ему делегата:

void Main()
{
    DoSomething(msg => Console.WriteLine(msg));

    using (var writer = new StreamWriter(@"d:\temp\test.txt"))
    {
        DoSomething(msg => writer.WriteLine(msg));
    }
}

public delegate void LogDelegate(string message);

public static void DoSomething(LogDelegate logger)
{
    logger("Starting");
    for (int index = 0; index < 10; index++)
        logger("Processing element #" + index);
    logger("Finishing");
}

Сначала он войдет в консоль, а затем повторно запустит метод и зарегистрируется в файле.

0

Используйте делегат в следующих случаях: 1. Используется шаблон проектирования (обработчики событий) 2. Для класса может потребоваться более одной реализации метода. 3.Thread-реализация (Thread Start, sleep и т.д.).

для получения дополнительной информации см. https://msdn.microsoft.com/en-us/library/ms173173.aspx:

Ещё вопросы

Сообщество Overcoder
Наверх
Меню