C#中的委托(二)
一、Action<T>和Func<T>委托
除了上篇描述的为每个参数和返回类型定义一个新委托类型之外,还可以使用Action<T>和Func<T>委托。通过T的标示,我们可以知道这是两个泛型委托。
二、Action<T>
其中Action<T>委托表示引用一个void返回类型的方法。这个委托存在不同的变体,可以传递最多16种不同的参数类型。如:Action<in T1>表示调用带一个参数的方法(返回类型为void),Action<in T1,in T2>表示两个参数,Action<in T1.....in T16>表示16个参数(最多16个);在这就以上篇中数据操作类,加以改造:
public class MathOperation
{
public static void Add(int x, int y)
{
int result = x + y;
Console.WriteLine("x+y={0}", result);
}
public static void Reduce(int x, int y)
{
int result = x - y;
Console.WriteLine("x-y={0}", result);
}
public static void Process(Action<int, int> action, int x, int y)
{
action(x, y);
}
}
执行代码:
Action<int, int>[] operation = {
MathOperation.Add,
MathOperation.Reduce
};
for (int i = 0; i < operation.Length; i++)
{
Console.WriteLine("执行第{0}个委托方法", i);
for (int j = 1; j < 10; j++)
{
MathOperation.Process(operation[i], i, j);
Thread.Sleep(20);
}
}
输出结果:
三、Func<T>
Func<T>调用带返回类型的方法。与Action<T>类似,Func<T>也定义了不同的变体,至多可以16个参数类型和一个返回类型。Func<out TResult>委托类型可以调用带返回类型且无参的方法,Func<in T,out TResult>表示带有一个参数的方法。我们继续在数据操作类上改造:
public class MathOperation
{
public static int Add(int x, int y)
{
int result = x + y;
return result;
}
public static int Reduce(int x, int y)
{
int result = x - y;
return result;
}
public static void Process(Func<int, int, int> action, int x, int y)
{
int result = action(x, y);
Console.WriteLine("执行结果为:{0}", result);
}
}
执行代码:
Func<int, int,int>[] operation = {
MathOperation.Add,
MathOperation.Reduce
};
for (int i = 0; i < operation.Length; i++)
{
Console.WriteLine("执行第{0}个委托方法", i);
for (int j = 1; j < 10; j++)
{
MathOperation.Process(operation[i], i, j);
Thread.Sleep(20);
}
}
执行结果:
四、员工工资排序实例
首先定义一个员工类
public class Empolyee
{
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 工资
/// </summary>
public decimal Salary { get; set; }
public Empolyee(string name, decimal salary)
{
this.Name = name;
this.Salary = salary;
}
/// <summary>
/// 重构
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("{0}的工资为:{1}", Name, Salary);
}
/// <summary>
/// 定义一个比较员工工资的静态方法(用于向通用排序类传值)
/// </summary>
/// <param name="e1"></param>
/// <param name="e2"></param>
/// <returns></returns>
public static bool CompareTo(Empolyee e1, Empolyee e2)
{
return e1.Salary < e2.Salary;
}
}
然后创建一个排序类:
public class SortUtil
{
public static void Sort<T>(IList<T> arrList, Func<T, T, bool> compare)
{
冒泡排序
//for (int i = 0; i < arrList.Count - 1; i++)
//{
// for (int j = i + 1; j < arrList.Count - 1; j++)
// {
// if (compare(arrList[i], arrList[j]))
// {
// var temp = arrList[i];
// arrList[i] = arrList[j];
// arrList[j] = temp;
// }
// }
//}
bool result = true;
do
{
result = false;
for (var i = 0; i < arrList.Count - 1; i++)
{
if (compare(arrList[i], arrList[i + 1]))
{
T temp = arrList[i];
arrList[i] = arrList[i + 1];
arrList[i + 1] = temp;
result = true;
}
}
}
while (result);
}
}
执行代码:
Empolyee[] list = {
new Empolyee("A",12.3M),
new Empolyee("B",12.4M),
new Empolyee("C",12.2M),
new Empolyee("D",12.5M),
new Empolyee("E",12.1M)
};
SortUtil.Sort<Empolyee>(list, Empolyee.CompareTo);
foreach (var item in list)
{
Console.WriteLine(item.ToString());
}
执行结果: