委托
委托的定义
是一种类型 这个类型赋值方法的引用
委托的声明
delegate 返回值 方法名(参数);
举例
delegate string GetString();//声明了一种委托类型 这个类型的名字是GetString
public static void Main(){
string x=100;
//GetString的实例化 指向的是int.ToString() 这个方法
1. GetString gs=new GetString(x.ToString);
2. 常用 GetString gs=x.ToString;
//通过委托实例调用方法
1. string ss=gs();
2. string ss=gs.Invoke();
Console.WriteLine(gs);
Console.ReadKey;
}
Action和Func
Action 是内置定义好的委托类型 可以直接使用 注意:Aciton没有返回值!
Func 有返回值是返回这类型
public static void Main(){
Action<int> a=GetInt; //Action委托的实例化 参数必须对应
a(10);//调用 有参数 必须输入形参
}
public void GetInt(int i){
Console.WritrLine(i.ToString)
}
public static void Main(){
Func<int> a =GetInt; //这个<int>是返回值类型
Func<int,int> b = GetInt;//string 是参数类型 int 是返回值类型
}
public int GetInt(){
return 1;
}
public int GetInt(int i){
return i+1;
}
扩展:委托的使用(冒泡排序)
//员工类 有名字 工资两个属性
public class Employee
{
private string name;
private int salary;
public string Name
{
get { return name; }
private set { name = value; }
}
public int Salary
{
get { return salary; }
private set { salary = value; }
}
public Employee(string name,int salary)
{
this.Name = name;
this.Salary = salary;
}
//比较工资的静态方法
public static bool Compare(Employee e1,Employee e2)
{
if (e1.Salary > e2.Salary) return true;
return false;
}
}
public static void Main(string[]arg){
Employee[] employees=new Employee[]
{
new Employee("da",123),
new Employee("dss", 4564),
new Employee("aw", 12),
new Employee("rf", 56),
new Employee("cv", 789),
new Employee("dxza", 666)
}
CommonSort<Employee>(employees,Employee.Compare);
}
// 参数:比较的数组,和比较数组的方法
public static void CommonSort<T>(T[] sortArray,Func<T,T,bool> CompareMethod)
{
bool swapped=true;//是否需要比较继续比较的《标志变量》
do
{
swapped=false;
for(int i=0;i<sortArray.Length-1;i++)
{
if(CompareMethod(sortArray[i],sortArray[i+1])) //如果比了一轮都不需要交换数据 swapped为false
{
T temp=sortArray[i];
sortArray[i]=sortArray[i+1];
sortArray[i+1]=temp;
swapped=true; //需要继续比较
}
}
}while(swapped)
}
多播委托
委托可以指向多个方法,按顺序调用。 但是 如果有返回值 多播委托只能得到最后一个方法的结果,一般我们都把多播委托的返回类型声明为void
public static void Main(string[] args){
Action a1=Method1;
a1+=Method2;
a1-=Method1;
a.();
//这里用 a1.GetInvovationList();的方法 返回一个Delegate[]的数组
Delegate[] delegates= a1.getInvovationList();
foreach(Delegate del in delegates)
{
del();
}
}
匿名方法
匿名方法本质上是一个方法,只是没有名字
public static void Main(string[] args)
{
Func<int,int,int> Method=delegate(int arg1,int arg2)
{
return arg1+arg2;
};
int value=7;
//lambda表达式
Func<int,int,int> Method2 =(arg1,arg2)=> //lambda表达式的参数不需要声明类型
{
return arg1+arg2+value; //可以访问lambda表达式块 外部的变量
};
}
事件
事件(event)基于委托,为委托提供了一个发布/订阅机制,可以说事件是一种特殊签名的委托。
注意:事件不能在类外部调用!!!
public class Cat
{
private string name;
private string color;
public Cat(string name,string color)
{
this.name = name;
this.color = color;
}
public void CatComing()
{
Console.WriteLine(color + "的" + name + "来了!!");
if (catCome!=null)
{
catCome();
}
}
public delegate void CatCome();
public CatCome catCome; // 委托 可以直接在外部调用 cat.catCome(); 会导致不安全 这是猫的行为在外部使用 会产生逻辑错误
public event CatCome catComeEventHandler; //事件 事件不能在外部调用
}
总结:事件是一种特殊的委托。