1.什么是委托?
委托是一种可以指向方法的数据类型,可以声明委托类型变量
声明委托的方式,使用delegate关键值来声明。
具体格式:delegate 返回值类型 委托类型名(参数)
例:delegate int MyDelegate(int a,string b)
2.那么如何去创建一个委托类型的对象呢:MyDelegate demoDel = new MyDelegate(SayHello);
下面的写法是错误的:MyDelegate demoDel = new MyDelegate(SayHello());因为这样写表示是调用方法。
但是可以使用下面的简便方法来创建委托类型对象:MyDelegate demoDel =SayHello;虽然你使用这种简便方法进行创建,但是
编译器会自动给你编译成第一种MyDelegate demoDel = new MyDelegate(SayHello);
class Program
{
static void Main(string[] args)
{
Mydelegate mydelegate = new Mydelegate(SayHello);
mydelegate("张三");
Console.ReadKey();
}
public static int SayHello(string name )
{
Console.WriteLine(name+"你好呀");
return 1;
}
}
delegate int Mydelegate(string name);
上述结果出来非常简单:张三你好呀
如果我们在上面代码段中加入下列的代码,就会发生错误,抛出异常
mydelegate = null;
mydelegate("报错");
3.下面我们用一个实际的例子来看看实际中怎么使用委托
要比较一个数组中的最大值,最后打印出最大值
public class Test
{
public static void Main(string[] args)
{
int[] nums = { 5, 23, 3, 323, 3543, 21423, 214 };
Console.WriteLine("最大值为" + GetMax(nums));
Console.ReadKey();
}
public static int GetMax(int[] nums)
{
int max=nums[0];
for (int i = 1; i < nums.Length; i++)
{
if(nums[i]>max)
{
max = nums[i];
}
}
return max;
}
}
上面这个方法只能查找整型数组的最大值,不利于扩展,如果我们要比较float、Double、或者自定义类的比较该怎么办呢??
下面我们使用委托来解决这个问题。
我们发现这个不同类型使用的比较最大值的方法都是差不多的,只是在比较前不知道要传入什么类型的数据,所以我们在比较的时候使用委托来解决。
public class Test
{
public static void Main(string[] args)
{
object[] nums = { 11, 2, 2, 3, 34, 3, 543, 5, 251, 234 };
CompareNum cpn = new CompareNum(CompareNum);
int max = (int)GetMax(nums, cpn);
Console.WriteLine(max);
Console.ReadKey();
}
/// <summary>
/// 用于比较整型数据的方法
/// </summary>
/// <param name="obj1"></param>
/// <param name="obj2"></param>
/// <returns></returns>
public static bool CompareNum(object obj1, object obj2)
{
int num1 = (int)obj1;
int num2 = (int)obj2;
return num1 > num2;
}
public static object GetMax(object[] nums, CompareNum cpn)
{
object max = nums[0];
for (int i = 1; i < nums.Length; i++)
{
if (!cpn(max, nums[i]))
{
max = nums[i];
}
}
return max;
}
}
public delegate bool CompareNum(object obj1, object obj2);
上面的方法就是经过改造的版本,接下来我们扩展一个Double类型和Person类比较age的方法
/// <summary>
/// 用于比较Double类型数据
/// </summary>
/// <param name="obj1"></param>
/// <param name="obj2"></param>
/// <returns></returns>
public static bool CompareNumDouble(object obj1, object obj2)
{
Double num1 = (Double)obj1;
Double num2 = (Double)obj2;
return num1 > num2;
}
Main方法内容
CompareNum cpn = CompareNumDouble;
object[] nums = { 11.2, 2.2, 2.34, 3.34, 0.34, 2.3, 23.543, 2134.5, 4.251,3.234 };
Double max = (Double)GetMax(nums, cpn);
Console.WriteLine(max);
Console.ReadKey();
运行结果:2134.5
接下来我们写Person类
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
写入比较Person类Age属性的方法
/// <summary>
/// 用于Person类比较方法
/// </summary>
/// <param name="obj1"></param>
/// <param name="obj2"></param>
/// <returns></returns>
public static bool CompareNumPerson(object obj1, object obj2)
{
Person num1 = (Person)obj1;
Person num2 = (Person)obj2;
return num1.Age > num2.Age;
}
最后在Main方法中测试
Person[] p1 = { new Person() { Age = 12, Name = "张三" }, new Person() { Age = 32, Name = "李四" }, new Person() { Age = 22, Name = "王五" } };
CompareNum cpn = new CompareNum(CompareNumPerson);
Person maxPerson = (Person)GetMax(p1, cpn);
Console.WriteLine("最大年龄的人是"+maxPerson.Name+"年龄为"+maxPerson.Age);
Console.ReadKey();
结果为:最大年龄的人是李四年龄为32
在上面的例子中,我们对于GetMax方法没有做任何的改变,只是添加了对应类型的比较方法
4.委托与泛型结合
public static T GetMax<T>(T[] nums, CompareNum<T> cpn)
{
T max = nums[0];
for (int i = 1; i < nums.Length; i++)
{
if (!cpn(max, nums[i]))
{
max = nums[i];
}
}
return max;
}
}
public delegate bool CompareNum<T>(T obj1, T obj2);
会产生同样的结果
5.Func和Action
在平时的时候,一般不需要我们自己去写泛型委托,.Net中内置两个泛型委托Func、Action(在“对象浏览器”的mscorlib的System下),日常开发中基本不用自定义委托类型了。
我们用Func、 Action代替之前的委托
Action是带返回值的,Func是无返回值的
class Program
{
public static void Main(string[] args)
{
Func<string, string> func = new Func<string, string>(PrintName);
Console.WriteLine(func("里斯u"));
Console.ReadKey();
}
public static string PrintName(string name)
{
return name;
}
}
public static void Print(string name)
{
Console.WriteLine(name);
}
Action<string> act = new Action<string>(Print);
Print("潇洒回复");
Console.ReadKey();
---本博客是学习以后记录知识,如有侵权,请联系删除!!!