.Net 委托 delegate 学习

时间:2022-06-12 16:36:19
一、什么是委托:
委托是寻址方法的.NET版本,使用委托可以将方法作为参数进行传递。委托是一种特殊类型的对象,其特殊之处在于委托中包含的只是一个活多个方法的地址,而不是数据。
 
二、使用委托: 关键字:delegate
1.声明:
      public delegate void DoNothing();//定义一个无返回值,无参数的委托
     public delegate int GetNum(int i); //定义有一个返回值int ,参数int 的委托
2.创建方法:
public static void DoSome()//无参无返回值的方法
{
Console.WriteLine("DoSome");
}
public static int TotalNum(int num)//有一个返回值int ,参数int 的方法
{
return num * num;
}
 
3.注册委托:
DoNothing doNothing = new DoNothing(DoSome);
//或者直接写出DoNothing doNothing = DoSome;
 
GetNum getNum = AddNum;//注册委托
 
4.执行委托
doNothing.Invoke();//执行委托  也可以直接 doNothing();
Console.WriteLine(getNum.Invoke(10));//执行委托并且打印
 
三、委托的意义
传递方法;把方法包裹起来, 传递逻辑。异步多线程执行
 
四、.net framework3.5之后,系统定义好了2个委托,开发尽量使用框架自带委托,尽量使用Action和Func
Action 无返回值委托,Func 有返回值委托
 
Action要使用参数,就写Action<int,string,double> 最多可以到16个
 
Func要使用参数,就写成Func<int,string,double> 最多可以到17个, 最后一个为返回值,现在这个返回的就是double类型
 
Action act = DoSome;//Action 无返回值委托
act.Invoke();
 
 Func<int,int> func = new Func<int,int>(TotalNum)  ;
func(10);
 
 
五、多播委托
Action doSome = new Action(DoSome);
doSome += new Action(DoSome);
doSome += DoSome;
 
doSome();//按顺序执行,最后结果是执行3次DoSome方法
 
doSome -= DoSome;//减少一次DoSome执行
 
doSome();//按顺序执行,最后结果是执行2次DoSome方法
 
多播委托,按顺序执行,多播委托,用Action, Func带返回值的只执行完后,只得到最后一个结果,所以没有意义。
 
委托使用案例:一个学生类,一个学生管理静态类,可以通过委托,实现学生集合的筛选
 public class Student
{
public int Id { get; set; } public string Name { get; set; } public int ClassId { get; set; } public int Age { get; set; }
} public static class StudentManager
{
public static List<Student> students = new List<Student>()
{
new Student(){ Id=,Name="张三",ClassId=,Age= },
new Student(){ Id=,Name="李四",ClassId=,Age= },
new Student(){ Id=,Name="王五",ClassId=,Age= },
new Student(){ Id=,Name="赵六",ClassId=,Age= },
new Student(){ Id=,Name="杨幂",ClassId=,Age= },
new Student(){ Id=,Name="范冰冰",ClassId=,Age= },
new Student(){ Id=,Name="张学友",ClassId=,Age=},
new Student(){ Id=,Name="张三1",ClassId=,Age= },
new Student(){ Id=,Name="张三2",ClassId=,Age= },
new Student(){ Id=,Name="张三3",ClassId=,Age= },
new Student(){ Id=,Name="张三4",ClassId=,Age= },
new Student(){ Id=,Name="张三5",ClassId=,Age= },
new Student(){ Id=,Name="张三6",ClassId=,Age= },
new Student(){ Id=,Name="张三7",ClassId=,Age= },
new Student(){ Id=,Name="张三8",ClassId=,Age= },
new Student(){ Id=,Name="张三9",ClassId=,Age= },
new Student(){ Id=,Name="张三0",ClassId=,Age= },
new Student(){ Id=,Name="张三11",ClassId=,Age= },
new Student(){ Id=,Name="张三a",ClassId=,Age= },
new Student(){ Id=,Name="张三b",ClassId=,Age= },
new Student(){ Id=,Name="张三c",ClassId=,Age= },
new Student(){ Id=,Name="张三d",ClassId=,Age= },
new Student(){ Id=,Name="张三e",ClassId=,Age= },
new Student(){ Id=,Name="张三f",ClassId=,Age= },
new Student(){ Id=,Name="张三g",ClassId=,Age= },
new Student(){ Id=,Name="张三h",ClassId=,Age= },
new Student(){ Id=,Name="张三i",ClassId=,Age= },
new Student(){ Id=,Name="张三j",ClassId=,Age= },
new Student(){ Id=,Name="张三k",ClassId=,Age= },
}; public static List<Student> FindStudents(Func<Student,bool> func)
{
List<Student> stus = new List<Student>(); foreach (var item in students)
{
if (func(item))
{
stus.Add(item);
}
}
return stus;
} /// <summary>
/// 查找ClassId为3001的学生
/// </summary>
/// <param name="student">学生</param>
/// <returns>是否为3001班级的学生</returns>
public static bool GetClassId(Student student)
{
if (student.ClassId==)
{
return true;
} return false; }
/// <summary>
/// 年龄大于20的学生
/// </summary>
/// <param name="student"></param>
/// <returns></returns>
public static bool GetBigAge(Student student)
{
if (student.Age>)
{
return true;
}
return false;
}
/// <summary>
/// 年龄大于15 并且ClassId为1021
/// </summary>
/// <param name="student"></param>
/// <returns></returns>
public static bool GetStuByClassIdAndAge(Student student)
{
if (student.Age > && student.ClassId==)
{
return true;
}
return false;
} }

下面这个是在Main方法中执行查询学生

//List<Student> stus = StudentManager.students;

            //Console.WriteLine("姓名---年龄---班级--编号");
//foreach (var item in stus)
//{
// Console.WriteLine(item.Name+"---"+item.Age+"---"+item.ClassId+"---"+item.Id);
//} List<Student> stus1= StudentManager.FindStudents(StudentManager.GetStuByClassIdAndAge); Console.WriteLine("姓名---年龄---班级--编号");
foreach (var item in stus1)
{
Console.WriteLine(item.Name + "---" + item.Age + "---" + item.ClassId + "---" + item.Id);
}