Func<>
- универсальный делегат - его очень удобно использовать, потому что вам не нужно создавать свой собственный делегат для каждой комбинации аргумент / возвращаемый тип.
Ранее вам приходилось писать что-то вроде:
public delegate long MyDelegate( int number );
public void Method( IEnumerable<int> list, MyDelegate myDelegate )
{
foreach( var number in list )
{
myDelegate( number );
}
}
Вы должны были опубликовать свой делегат, чтобы пользователь мог правильно вызвать ваш метод. Особенно, когда вам нужно несколько разных делегатов, вы заканчиваете тем, что публикуете по одному для каждого списка аргументов и типа возвращаемого значения.
С Func<>
вы просто пишете:
public void Method( IEnumerable<int> list, Func<int, long> myDelegate )
{
foreach( var number in list )
{
myDelegate( number );
}
}
Это означает то же, что и в первом примере кода - Func<int, long>
определяет делегата, который принимает один целочисленный аргумент и возвращает длинное значение.
Конечно, вы также можете использовать более длинные списки параметров: Func<int, int, bool, long>
будет по-прежнему возвращать значение long , в то время как оно принимает два ints и bool значение , Если вы хотите делегата без возвращаемого значения, вы должны будете использовать Action<>
, который будет иметь void в качестве типа возврата.
РЕДАКТИРОВАТЬ (по запросу): Как вызвать метод в моем примере :
Для вызывающего абонента нет разницы между решением с MyDelegate
или Func<>
. В обоих случаях у него есть три варианта вызова метода:
Использование лямбда-нотации (требуется C # 3.0, вероятно, лучшее решение для коротких методов):
Method( myList, i => i * i );
Используя анонимный метод (требуется C # 2.0):
Method( myList, delegate( int i )
{
return i * i;
} );
Или используя реальный метод в качестве аргумента:
Method( myList, Square );
private static long Square( int number )
{
return number * number;
}