Почему Action <T>и Predicate <T>используются или определяются как делегаты? - PullRequest
4 голосов
/ 27 сентября 2010

Может кто-нибудь объяснить, какова точная причина использования Action<T> и Predicate<T> в качестве делегатов в C #

Ответы [ 5 ]

11 голосов
/ 27 сентября 2010

Вы спрашиваете, почему они существуют или почему они определены как делегаты?

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

public delegate void MyDelegate(int size);

А затем создать его:

MyDelegate proc = new MyDelegate((s) => { // do stuff here });

Конечно, вам придется делать это для каждого другого типа, который вы хотите иметь такой метод.

Или, вы можете просто использовать Action<T>:

Action<int> proc = new Action<int>((s) => { /* do stuff here */ });

КонечноВы можете сократить это до:

Action<int> proc = (s) => { /* do stuff here */ });

Что касается "почему они являются делегатами?"Потому что так обрабатываются ссылки на функции в .NET: мы используем делегаты.Обратите внимание на сходство в приведенных выше примерах.То есть MyDelegate концептуально то же самое, что и Action<int>.Они не точно одно и то же, поскольку они имеют разные типы, но вы можете легко заменить каждый экземпляр этого MyDelegate в программе на Action<int>, и программа будет работать.

4 голосов
/ 27 сентября 2010

Что еще они будут? Делегаты являются наиболее гибким и наиболее близким к тому, что Action<T>, Predicate<T> и Func<T> modlling - список вызовов с указанными типами параметров (или делегатами).

3 голосов
/ 27 сентября 2010

Лучший способ объяснить, почему была выбрана идиома выполнения действий и предикатов с использованием делегатов Action<T> и Predicate<T>, - это сначала рассмотреть альтернативу. Как вы могли бы сделать то же самое без делегатов? Следующим лучшим вариантом было бы иметь интерфейсы IAction и IPredicate и заставлять разработчиков объявлять класс и реализовывать соответствующий интерфейс для каждого необходимого типа операции. Но проблема этого подхода заключается в том, что он требует больше усилий, большего количества классов и меньшего количества поддерживаемого кода. Подход делегата намного удобнее, потому что вы можете написать логику, в которой он будет использоваться, используя анонимные методы или лямбда-выражения.

2 голосов
/ 27 сентября 2010

Потому что они являются делегатами.

1 голос
/ 27 сентября 2010

Вы смотрите на проблему с неправильной точки зрения.

Вопрос не должен звучать так: "Почему делегаты Action<>, Func<> & Predicate<>?"(Ответ на это «потому что они должны быть»)

Реальный вопрос: «Почему у нас есть конкретные именованные объекты для обработки простых задач делегирования? Зачем использовать Action<> в месте, гдеобычный делегат будет работать? "

Ответ заключается в том, что эти конкретные делегаты часто используются в самой CLR, и поскольку они используются в методах CLR, где конечные разработчики должны будут определять вызываемый методдекларация для делегата должна быть публичной.Таким образом, Microsoft могла бы определить тысячи делегатов, каждый из которых использовался только одним методом CLR, или определить простой способ указать, какой тип делегата необходим.

...