использовать Func <> (или Action <>) или создать собственный делегат? - PullRequest
12 голосов
/ 16 декабря 2010

Какой из них лучше, скажем, в типе параметра в методе (не связан с LINQ). Очевидно, что Func лучше, так как он проще, более нагляден, и если все его используют, все станет совместимым (хорошо). Однако я заметил, что Microsoft использует свой собственный делегат в некоторых библиотеках, например, обработчиках событий. Итак, каковы преимущества и недостатки любого из них? когда я должен использовать это?

Правки:

  • Очевидно, что Func <> был доступен только в версии 3.5, поэтому это может быть основной причиной, по которой я видел делегатов не из Func. Любая другая причина не использовать Func? (пример: это из .NET4)

  • Тот же вопрос относится и к действию <>

Ответы [ 5 ]

5 голосов
/ 16 декабря 2010

Func <> полезно, когда очень ясно, для чего они используются, а количество входов мало.

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

1 голос
/ 16 декабря 2010

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

Часть этого является исторической: API были определены до C # 3 / .NET3, когда были добавлены Action<> и Func<>.Для событий EventHandler<T> - лучший выбор для событий, поскольку он обеспечивает соблюдение правильного соглашения.

1 голос
/ 16 декабря 2010

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

Однако иногда пользовательские делегаты делают код более понятным.

1 голос
/ 16 декабря 2010

Они для всех целей одинаковы, за исключением случая, когда метод имеет параметр Expression. Они должны быть определены как «лямбда», а не delegate. Это было бы очень проблематично при работе с IQueryable и получении вместо него IEnumerable, вызванного / разрешенного (например, LINQ2SQL).

0 голосов
/ 16 декабря 2010

Вы всегда можете создать класс, который содержит n входных данных в качестве свойств класса и передать объекту класса один вход в func <> делегат

...