Делегаты в C # (не) объясненном примере - выглядит так же, как вызов метода - PullRequest
2 голосов
/ 21 января 2012

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

double tot1 = CalcTotalMethod1(100.34);
double tot2 = CalcTotalMethod2(100.34);

вместо

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);

Этопример:

public static double CalcTotalMethod1(double amt)
{
    return amt * .014;
}

public static double CalcTotalMethod2(double amt)
{
    return amt * .056 + 42.43;
}


public delegate double calcTotalDelegate(double amt);

public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal)
{
    return calcTotal(amt);
}

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);

Ответы [ 4 ]

4 голосов
/ 21 января 2012

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

var somethingTricky = LotsOfWork(amt);
var intermediateValue = calcTotal(somethingTricky);
return SomeMoreWork(intermediateValue);

Суть здесь: вызывающему не нужно знать, что происходит внутри CalcMyTotal - ему просто нужно предоставить какой-то механизм для «вычисления итогов»; и CalcMyTotal не нужно ничего знать о задействованном механизме. Вы можете думать об этом как об интерфейсе с одним методом.

Для полноты вы также можете сделать это (возможно, более четко) как:

public static double CalcMyTotal(double amt, Func<double,double> calcTotal) {...}

(обратите внимание на использование Func<...>) и вызывайте с использованием лямбда-синтаксиса:

double tot1 = CalcMyTotal(100.34, amt => amt * 0.014);
4 голосов
/ 21 января 2012

Это потому, что вы имеете дело с тривиальными примерами .....

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

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

3 голосов
/ 21 января 2012

Некоторые различия:

  • Делегаты допускают многоадресную рассылку (т. Е. Более одного элемента типа делегата в его списке вызовов).
  • Делегаты допускают некоторый уровень развязки между вызывающим и конкретной вызываемой функцией.
  • Вышеприведенное позволяет отправлять делегатов в функции, которые ничего не знают о подписчиках и реализации.Затем у вас есть реализация шаблона издатель / подписчики.
  • Делегаты - это ступенька к созданию событий, которые используют делегатов для уведомления 0-N подписчиков о том, что определенное событие произошло вместе с передачей.данные, описывающие детали события для всех подписчиков.
2 голосов
/ 21 января 2012

Делегаты наиболее полезны, когда вам нужно передать ссылку на метод.Примеры включают события в C # и сортировку с помощью пользовательского компаратора .

Пример последнего:

class Thing
{
    private int value;

    public static int CompareTwoThings(Thing one, Thing other)
    {
        if (one.value < other.value) return -1;
        if (one.value > other.value) return 1;
        return 0;
    }
}

// elsewhere
List<Thing> things = GetSomeThings();
things.Sort(Thing.CompareTwoThings);

Конечно, в этомна тот случай, если вам действительно нужно вместо этого Thing реализовать IComparable, но это всего лишь пример того, как вы можете использовать делегата в качестве пользовательской функции сортировки.

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