Делегаты Action<T> и Func<T>
50C# --- Руководство по C# --- Делегаты Action<T> и Func<T>
Вместо определения нового типа делегата с каждым типом параметра и возврата можно использовать делегаты Action<T> и Func<T>. Обобщенный делегат Action<T> предназначен для ссылки на метод, возвращающий void. Этот класс делегата существует в различных вариантах, так что ему можно передавать до 16 разных типов параметров.
Класс Action без обобщенного параметра предназначен для вызова методов без параметров, Action<in Т> — для вызова метода с одним параметром, Action<in T1, in Т2> — для вызова метода с двумя параметрами и Action<in T1, in Т2, in ТЗ, in Т4, in Т5, in Т6, in Т7, in Т8> — для вызова метода с восемью параметрами.
Делегаты Func<T> могут использоваться аналогичным образом. Func<T> позволяет вызывать методы с типом возврата. Подобно Action<T>, Func<T> определен в разных вариантах для передачи до 16 типов параметров и типа возврата. Func<out TResult> — тип делегата для вызова метода с типом возврата, но без параметров, Func<in T1, out TResult> — для метода с одним параметром, a Func<in T1, in T2, in ТЗ, in T4, out TResult> — для метода с четырьмя параметрами.
Давайте рассмотрим пример:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class ArrSort
{
// Реализуем обобщенный метод сортировки
public static void Sort<T>(IList<T> sortArray, Func<T, T, bool> res)
{
bool mySort = true;
do
{
mySort = false;
for (int i = 0; i < sortArray.Count - 1; i++)
{
if (res(sortArray[i + 1], sortArray[i]))
{
T j = sortArray[i];
sortArray[i] = sortArray[i + 1];
sortArray[i + 1] = j;
mySort = true;
}
}
} while (mySort);
}
}
class UserInfo
{
public string Name { get; private set; }
public string Family { get; private set; }
public decimal Salary {get; private set;}
public UserInfo(string Name, string Family, decimal Salary)
{
this.Name = Name;
this.Family = Family;
this.Salary = Salary;
}
// Переопределим метод ToString
public override string ToString()
{
return string.Format("{0} {1}, {2:C}",Name,Family,Salary);
}
// Данный метод введен для соответствия сигнатуре
// делегата Func
public static bool UserSalary(UserInfo obj1, UserInfo obj2)
{
return obj1.Salary < obj2.Salary;
}
}
class Program
{
static void Main()
{
UserInfo[] userinfo = { new UserInfo("Dmitry","Medvedev",50000000000),
new UserInfo("Alex","Erohin",100),
new UserInfo("Alexey","Volkov",40000),
new UserInfo("Wiley","Coyote",1000000)};
ArrSort.Sort(userinfo, UserInfo.UserSalary);
Console.WriteLine("Сортируем исходный объект по доходу: \n" +
"-------------------------------------\n");
foreach (var ui in userinfo)
Console.WriteLine(ui);
Console.ReadLine();
}
}
}