委托是一类行为的抽象。是方法的引用,是一种数据类型
委托可以实现对方法的【间接】调用! 灵活=维护性好!
委托的定义:委托是一种数据类型;委托代表的是方法,当调用委托时就是调用了这个方法。
【委托能存储方法的地址{ 引用}】【间接调用】
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DemoDelegate1
{
//调用端
class DelagateDemo1
{
static void Main(string[] args)
{
//步骤2:实例化委托(绑定f1方法)
Handler handlerObj = new Handler(F1);
//绑定A类的方法new Handler(A.F);
//步骤3:调用委托
handlerObj();
}
static public void F1()
{
}
}
//定义端
//步骤1:声明委托,定义委托
delegate void Handler();
//delegate int CalHandler(int a, int b);
class A
{
public static void F()
{
Console.WriteLine("委托的使用步骤");
}
}
}
使用案例↓
namespace 事件的使用案例_猫和老鼠
{
class Program
{
static void Main(string[] args)
{
//猫 mao = new 猫();
//老鼠 laoshu = new 老鼠();
//mao.叫();
//laoshu.逃跑();
猫 mao = new 猫();
老鼠 laoshu = new 老鼠();
//步骤2:注册事件
mao.叫+=new Handler(laoshu.逃跑);//添加老鼠跑行为
//mao.叫-= laoshu.逃跑;
//步骤4:
mao.Notify();
Console.Read();
}
}
//1.1 定义一个委托
delegate void Handler();//定义一个委托
class 猫
{
//public void 叫()
//{
// Console.WriteLine("miaomiao");
//}
//步骤1.2:定义事件
//public event Handler 叫;
public Handler 叫;
//步骤3:触发事件 固有的写法
public void Notify()
{
if(叫!=null)//判断事件有没有执行
{
Console.WriteLine("miaomiao");
叫();//调用事件的方法
}
}
}
class 老鼠
{
public void 逃跑()//老鼠逃跑行为
{
Console.WriteLine("jiji。。。。");
}
}
}
多播委托:一个委托对象关联多个方法 只返回最后方法的结果↓
所以:委托有返回值不适合多播执行!委托无返回值适合多播执行
namespace DemoDelegate2
{
//调用端
class DelagateDemo1
{
static void Main(string[] args)
{
//步骤2:实例化委托
CalHandler handlerObj = new CalHandler(Add);
handlerObj = handlerObj + new CalHandler(Divide);
//步骤3:调用委托
int re=handlerObj(6,2);
}
static public int Add(int a,int b)
{
return a + b;
}
static public int Divide(int a, int b)
{
return a/b;
}
}
//定义端
//步骤1:声明委托,定义委托
delegate int CalHandler(int a, int b);
}
实例化委托多种写法
委托的使用步骤:三步 1:定义2:实例化委托(多种写法) 3:调用委托
方式一、二:基本传统标准的写法,适合于: 委托已有的方法
Handler handler = new Handler(Fun);
Handler handler = Fun; //简化的写法 等号右边 表示的是委托对象
方式三:匿名方法,适合于:
功能简单少量代码可以完成,且该功能不需要在其它地方复用.
Handler handler = delegate(int a) 等号右边 表示的是委托对象=匿名方法
{
for (int i = 0; i < a; i++)
Console.WriteLine("HAHA");
};
方式四:Lambda 表达式,适合于:
写法一:功能简单少量代码可以完成,且该功能不需要在其它地方复用
写法二:功能代码超简单,一行代码可以完成
Lambda 表达式语法:
委托类型 委托对象名=Lambda 表达式;
写法一 (参数)=>{语句} => goto
(参数1,参数2)=> 一行代码;return不能写!
简化写法二 一个参数=>一行代码;return不能写!
Handler handler = (p) => Console.WriteLine(p + "HAHA");
等号右边 表示的是委托对象=Lambda 表达式=匿名方法
namespace DemoDelegate
{
//
class EX3
{
static void Main33()
{
//2> 4种写法
//Handler handlerObj = new Handler(Fun);//111
//Handler handlerObj = Fun;//222
//Handler handlerObj = delegate(Person p) { ///333
// return p.Age;
//};
Handler handlerObj =p=>p.Age; //444
//3>
Person person=new Person(){
Id=1, Name="aa", Age=20
};
int re = handlerObj(person);
}
//static int Fun(Person p)
//{
// return p.Age;
//}
}
//定义端 1>
public delegate int Handler(Person p); //从一个对象中选一个属性的值 Person id或age
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
}
Lambda 表达式进阶用法↓
namespace DemoDelegate444
{
//
class EX4
{
static void Main()
{
//2>
Handler handlerObj = (list, id) =>
{
Person person = null;
foreach (var p in list)
{
if (p.Id == id)
{
person = p;
break;
}
}
return person;
};
//3>
List<Person> arr = new List<Person>
{
new Person(){Id = 1,Name = "aa",Age = 20},
new Person(){Id = 2,Name = "bb",Age = 22}
};
var re = handlerObj(arr, 2);
}
}
//定义端 1>
public delegate Person Handler(List< Person> list,int id);
//从一个集合中选择编号=id的那个对象
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
}
委托实现方法的异步调用
同步调用方法:排队调用,前一个方法执行时,后一个方法等待它的结束后才能启动
异步调用方法:不排队调用,前一个方法如果异步调用,后一个方法不必等待它的结束就可启动,异步调用的方法是创建了一个新线程来工作的,与后一个方法所在不同的线程,各自独立,互不影响
Framework中的任何方法都可以异步调用。前提是通过委托引用该方法,使用BeginInvoke开启异步调用模式。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 异步调用
{
class Program
{
static Handler handlerObj = null;
static void Main(string[] args)
{
//同步调用=一个完,才能另一个 阻塞
//A obja = new A();
//obja.F1big();
//obja.F2();
//异步调用方式很多:1 委托【封装】2多线程【直接使用】
//2>实例化委托
A obja = new A();
handlerObj = new Handler(obja.F1big);
//3>开始异步调用
// AsyncCallback参数 要指定一个方法来取结果!
handlerObj.BeginInvoke(new AsyncCallback(FunGetRe), null);
obja.F2();
Console.ReadKey();
}
//定义一个取 结果的方法
//IAsyncResult 看做 服务员【监控器】
static void FunGetRe(IAsyncResult ar)
{
bool re = ar.IsCompleted;
// 4>结束异步调用【如果有返回值 可以取返回值】
if (re)
{
handlerObj.EndInvoke(ar);
Console.WriteLine("IsCompleted");
}
}
}
class A
{
public void F1big()
{
System.Threading.Thread.Sleep(3000);//3001,4000
Console.WriteLine("1111111111");
}
public string F2big(int a)
{
System.Threading.Thread.Sleep(3000);//3001,4000
Console.WriteLine("big big");
return a.ToString();
}
public void F2()
{
Console.WriteLine("222222");
}
}
//1>定义相应的委托
delegate void Handler ();
}