В чем преимущество использования делегата по сравнению с промежуточным методом? - PullRequest
2 голосов
/ 09 октября 2011

Есть ли причина использовать это:

bool flag;

public Form1()
{
    if (flag) byDelegate = square;
    else byDelegate = cube;
    Text = byDelegate(3).ToString();          
}

int square(int i) { return i * i; }
int cube(int i) { return i * i * i; }

delegate int delegate1(int x);
delegate1 byDelegate;

Вместо:

bool flag;

public Form2()
{
    Text = fakeDelegate(3).ToString(); 
}

int square(int i) { return i * i; }
int cube(int i) { return i * i * i; }

int fakeDelegate(int i)
{
    if (flag) return square(i);
    else return cube(i);
}

Спасибо.

Ответы [ 4 ]

5 голосов
/ 09 октября 2011

Делегаты обычно используются асинхронно для событий или передаются в методы / типы, так что метод, на который указывает делегат («указатели на функции»), может быть вызван позже. В вашем случае, похоже, нет никакого преимущества, поскольку вы делаете все синхронно.

Например

private Action<double> _performWhenFinished.

public Form1(Action<double> performWhenFinished)
{
    _performWhenFinished = performWhenFinished;        
}

public void CalculatePi()
{
   double pie = 0d;
    // Create a new thread, take 2 minutes to perform the task

    // Thread.Wait etc., then and run your delegate 
    _performWhenFinished(pie);
}

Как правило, вам не нужно объявлять своих собственных делегатов в версии 3.5 и выше, если вы не хотите, чтобы ваш код предоставлял немного больше смысла через эти объявления. Тип Action и тип Func (func предоставляет метод с возвращаемым значением) экономят ваши усилия.

1 голос
/ 09 октября 2011

fakeDelegate вовсе не является делегатом: это просто вызов метода (который, в свою очередь, вызывает один из двух других методов).

Теперь две причины, по которым делегаты - включая лямбду и «анонимный»функции "- очень полезны:

  1. Делегаты разрешают рассматривать функцию (или метод) как первоклассное значение. Первый пример в постеделает это, даже если это глупый пример (я делаю это иногда, но для подтверждения правильности одной формы над другой потребуется более широкий контекст).Чаще всего я использую это свойство для структуры данных, которая выглядит как IDictionary<String,MyDelegate>, которая затем используется как map["foo"](bar) или аналогичная - не могу сделать это без большой некрасивой диспетчеризации (или отражения) без значений функций первого класса!

  2. A / new / делегат может создать замыкание - то есть он может связывать свободные переменные в текущей лексической области.Это нельзя сделать обычными методами;ни cube, ни square не создадут замыкание, даже если группа методов может быть преобразована в делегат.Хотя в вышеприведенном примере нет никаких преимуществ, это может быть очень удобно , когда "просто нужно передать этот дополнительный маленький бит информации" в обратный вызов.

Поскольку ни один из этих двух случаев (особенно хорошо) не используется в примере, тогда ....

Счастливое кодирование.

1 голос
/ 09 октября 2011

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

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

1 голос
/ 09 октября 2011

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

В более общем смысле, вы можете думать о делегате как о «контракте» (или как «указатель на функцию», если ваш фон находится в C / C ++): вы говорите компилятору ожидать, что в этом месте функция получит заданный список параметров и предоставление заданного вывода (возможно, void), но вы не скажете ему, что на самом деле делает функция. Это «отделяет» тело метода от реальной реализации функции, давая вам свободу передавать несколько разных реализаций из разных частей вашего кода.

Кажется, есть довольно хорошие, более подробные объяснения в этой теме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...