public void Show() { Student student = new Student() { Id = 1, Name = "Jonty", Age = 18, ClassId = 1 }; student.Study(); { // 把方法包装成变量 invoke时执行方法 NoReturnNoPara methodNoPara = new NoReturnNoPara(this.DoNothing); // Invoke方法 委托里的方法 委托实例的调用 methodNoPara.Invoke(); // 等同于 methodNoPara(); // 执行 this.DoNothing(); } { // 多种实例化方式 NoReturnNoPara noPara = new NoReturnNoPara(this.DoNothing); NoReturnNoPara noPara1 = new NoReturnNoPara(DoNothingStatic); NoReturnNoPara noPara2 = new NoReturnNoPara(Student.StudyAdvanced); NoReturnNoPara noPara3 = new NoReturnNoPara(new Student().Study); } { // 多播委托:一个变量保存多个方法,可以增减,Invoke时按顺序执行 // 不能异步 // +=为委托实例按顺序增加方法 形成方法链 Invoke时按照顺序执行 NoReturnNoPara noPara = new NoReturnNoPara(this.DoNothing); noPara += new NoReturnNoPara(this.DoNothing); noPara += new NoReturnNoPara(DoNothingStatic); noPara.Invoke(); } }
public void Show() { //System.MulticastDelegate Student student = new Student() { Id = 123, Name = "靠谱一大叔", Age = 32, ClassId = 1 }; student.Study(); { //把方法包装成对象,invoke的时候自动执行方法 NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); //2 委托的实例化 method.Invoke(); //3 委托实例的调用 method(); this.DoNothing(); } //begininvoke { WithReturnNoPara method = new WithReturnNoPara(this.GetSomething); int iResult = method.Invoke(); iResult = method(); var result = method.BeginInvoke(null, null);//异步调用 method.EndInvoke(result); } { //多种途径实例化 { NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); } { NoReturnNoPara method = new NoReturnNoPara(DoNothingStatic); } { NoReturnNoPara method = new NoReturnNoPara(Student.StudyAdvanced); } { NoReturnNoPara method = new NoReturnNoPara(new Student().Study); } } { //多播委托:一个变量保存多个方法,可以增减;invoke的时候可以按顺序执行 //+= 为委托实例按顺序增加方法,形成方法链,Invoke时,按顺序依次执行 Student studentNew = new Student(); NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); method += new NoReturnNoPara(this.DoNothing); method += new NoReturnNoPara(DoNothingStatic); method += new NoReturnNoPara(Student.StudyAdvanced); method += new NoReturnNoPara(new Student().Study);//不是同一个实例,所以是不同的方法 method += new NoReturnNoPara(studentNew.Study); method.Invoke(); //method.BeginInvoke(null, null);//多播委托是不能异步的 foreach (NoReturnNoPara item in method.GetInvocationList()) { item.Invoke(); //item.BeginInvoke(null, null); } //-= 为委托实例移除方法,从方法链的尾部开始匹配,遇到第一个完全吻合的,移除且只移除一个,没有也不异常 method -= new NoReturnNoPara(this.DoNothing); method -= new NoReturnNoPara(DoNothingStatic); method -= new NoReturnNoPara(Student.StudyAdvanced); method -= new NoReturnNoPara(new Student().Study); method -= new NoReturnNoPara(studentNew.Study); method.Invoke(); } { WithReturnNoPara method = new WithReturnNoPara(this.GetSomething); method += new WithReturnNoPara(this.GetSomething2); method += new WithReturnNoPara(this.GetSomething3); int iResult = method.Invoke();//多播委托带返回值,结果以最后的为准 } }
public void Show() { { //多播委托有啥用呢?一个委托实例包含多个方法,可以通过+=/-=去增加/移除方法,Invoke时可以按顺序执行全部动作 //多播委托:任何一个委托都是多播委托类型的子类,可以通过+=去添加方法 //+= 给委托的实例添加方法,会形成方法链,Invoke时,会按顺序执行系列方法 Action method = this.DoNothing; method += this.DoNothing; method += DoNothingStatic; method += new Student().Study; method += Student.StudyAdvanced; //method.BeginInvoke(null, null);//启动线程来完成计算 会报错,多播委托实例不能异步 foreach (Action item in method.GetInvocationList()) { item.Invoke(); item.BeginInvoke(null, null); } //method.Invoke(); //-= 给委托的实例移除方法,从方法链的尾部开始匹配,遇到第一个完全吻合的,移除,且只移除一个,如果没有匹配,就啥事儿不发生 method -= this.DoNothing; method -= DoNothingStatic; method -= new Student().Study;//去不掉 原因是不同的实例的相同方法,并不吻合 method -= Student.StudyAdvanced; method.Invoke(); //中间出现未捕获的异常,直接方法链结束了 } //System.MulticastDelegate Student student = new Student() { Id = 96, Name = "一生为你" }; student.Study(); { NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); //2 委托的实例化 要求传递一个参数类型 返回值都跟委托一致的方法, method.Invoke(); //3委托实例的调用 参数和委托约束的一致 this.DoNothing(); //效果跟直接调用方法一致 method(); //可以省略.Invoke method.BeginInvoke(null, null); //启动一个线程完成计算 //method.EndInvoke(null); //委托就是一个类 为什么要用委托? 这个类的实例可以放入一个方法,实例Inovke时,就调用方法 //说起来还是在执行方法,为啥要做成三个步骤? 唯一的差别,就是把方法放入了一个对象/变量 } { //WithReturnWithPara method = new WithReturnWithPara(this.ParaReturn);//严格一致 //method += this.ParaReturn; //method.Invoke(out int a, ref b); } { WithReturnNoPara method = new WithReturnNoPara(this.Get); int i = method.Invoke(); int k = this.Get(); } { //Action Func .NetFramework3.0出现的 //Action 系统提供 0到16个泛型参数 不带返回值 委托 //Action action = new Action(this.DoNothing); Action action0 = this.DoNothing;//是个语法糖,就是编译器帮我们添加上new Action Action <int> action1 = this.ShowInt; Action <int, string, DateTime, long, int, string, DateTime, long, int, string, DateTime, long, int, string, DateTime, long> action16 = null; //Func 系统提供 0到16个泛型参数 带泛型返回值 委托 Func <int> func0 = this.Get; int iResult = func0.Invoke(); Func <int, string> func1 = this.ToString; Func <int, string, DateTime, long, int, string, DateTime, long, int, string, DateTime, long, int, string, DateTime, long, string> func16 = null; } { Action action0 = this.DoNothing; NoReturnNoPara method = this.DoNothing; //为啥框架要提供这种委托呢? 框架提供这种封装,自然是希望大家都统一使用Action/Func this.DoAction(action0); //this.DoAction(method); //委托的本质是类,Action和NoReturnNoPara是不同的类,虽然实例化都可以传递相同的方法,但是没有父子关系,所以是不能替换的 //就像Student和Teacher两个类,实例化都是传递id/name,但是二者不能替换的 //更进一步,框架中出现过N多个委托,委托的签名是一致的,实例化完的对象缺不能通用 //new Thread(new ParameterizedThreadStart()).Start(); //ThreadPool.QueueUserWorkItem(new WaitCallback()) //Task.Run(new Action<object>()); //本身实例化的时候,参数都是一样的,都是id/name,但却是不同的类型,导致没法通用 //Action和Func 框架预定义的,新的API一律基于这些委托来封装 //因为.Net向前兼容,以前的版本去不掉了,保留着,这是历史包袱 //此后,大家就不要再定义新的委托了,包括大家的作业 } { //多种途径实例化 实例化的限制就是方法的参数列表&返回值类型必须和委托约束的一致 { Action method = this.DoNothing; } { Action method = DoNothingStatic; } { Action method = new Student().Study; } { Action method = Student.StudyAdvanced; } } { Func <int> func = this.Get; func += this.Get2; func += this.Get3; int iResult = func.Invoke(); //结果是3 以最后一个为准,前面的丢失了。。所以一般多播委托用的是不带返回值的 } }
public void Show() { { NoReturnWithPara func = (x, y) => { }; func += (x, y) => Console.WriteLine("123");; func.Invoke(3, 4); } //System.MulticastDelegate Student student = new Student() { Id = 96, Name = "Summer" }; student.Study(); //Predicate<int> //Func<string> { NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);//2 委托的实例化 method.Invoke();//3 委托的调用 method(); //method.BeginInvoke(null, null); this.DoNothing(); } { NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); //当前类的实例方法 NoReturnNoPara method1 = new NoReturnNoPara(MyDelegate.DoNothingStatic); //当前类的静态方法 NoReturnNoPara method2 = new NoReturnNoPara(student.Study); //其他类的实例方法 NoReturnNoPara method3 = new NoReturnNoPara(Student.StudyAdvanced); //其他类的静态方法 } { NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); method += new NoReturnNoPara(this.DoNothing); method += new NoReturnNoPara(MyDelegate.DoNothingStatic); method += new NoReturnNoPara(student.Study); method += new NoReturnNoPara(Student.StudyAdvanced); method += new NoReturnNoPara(new Student().Study); method += new NoReturnNoPara(Student.StudyAdvanced); method += new NoReturnNoPara(() => Console.WriteLine("这里是lambda表达式")); //+=就是把多个方法按顺序排成列表,invoke时按顺序执行 //method.Invoke(); method -= new NoReturnNoPara(this.DoNothing); method -= new NoReturnNoPara(MyDelegate.DoNothingStatic); method -= new NoReturnNoPara(student.Study); method -= new NoReturnNoPara(new Student().Study); method -= new NoReturnNoPara(Student.StudyAdvanced); method -= new NoReturnNoPara(Student.StudyAdvanced); method -= new NoReturnNoPara(() => Console.WriteLine("这里是lambda表达式")); //-=就是从这个实例上,从后往前挨个匹配,找到第一个完全吻合的移除掉,且只移除一个,找不到不异常 method.Invoke(); //method.BeginInvoke(null, null); foreach (NoReturnNoPara item in method.GetInvocationList()) { item.BeginInvoke(null, null); } } }
public void Show() { Student student = new Student() { Id = 123, Name = "Ivan", Age = 32, ClassId = 1 }; student.Study(); { //把方法包装成变量, invoke 的时候自动执行方法 NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); // 2. 委托的实例化, 要求传入参数,参数为一个函数,函数必须与委托有同样的函数签名及返回值 { //3. 委托实例的调用, 相当于把传入的函数执行一遍 method.Invoke(); // Invoke 是delegate IL 中的方法, 相当于调用类的实例方法 method(); // 也可以直接省略Invoke进行调用 } } { // beginInvoke WithReturnNoPara method = new WithReturnNoPara(this.GetSomething); int iResult = method.Invoke(); iResult = method(); var result = method.BeginInvoke(null, null);// 异步调用 method.EndInvoke(result); } { // 多途径实例化 { NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); } { NoReturnNoPara method = new NoReturnNoPara(DoNothingStatic); } { NoReturnNoPara method = new NoReturnNoPara(Student.StudyAdvanced); } { NoReturnNoPara method = new NoReturnNoPara(new Student().Study); } } { // 多播委托: 一个变量保存多个方法,可以增减;Invoke时候可以按顺序执行 // += 为委托实例按顺序增加方法,形成方法链, Invoke时,是按顺序依次执行 NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); method += new NoReturnNoPara(this.DoNothing); method += new NoReturnNoPara(DoNothingStatic); method += new NoReturnNoPara(Student.StudyAdvanced); method += new NoReturnNoPara(new Student().Study);// 不是同一个实例, 所以是不同的方法 method += new NoReturnNoPara(student.Study); method.Invoke(); method.BeginInvoke(null, null); // 多播委托不能异步 foreach (NoReturnNoPara item in method.GetInvocationList()) { item.Invoke(); } // -= 为委托实例移除方法, 从方法链的尾部开始匹配, // 遇到第一个完全吻合的,移除且移除一个,没有也不异常 method -= new NoReturnNoPara(this.DoNothing); method -= new NoReturnNoPara(DoNothingStatic); method -= new NoReturnNoPara(Student.StudyAdvanced); method -= new NoReturnNoPara(new Student().Study); method -= new NoReturnNoPara(student.Study); method.Invoke(); { WithReturnNoPara method1 = new WithReturnNoPara(this.GetSomething); method1 += new WithReturnNoPara(this.GetSomething2); method1 += new WithReturnNoPara(this.GetSomething3); int result = method1.Invoke(); //多播委托带返回值,结果以最后的为准 Console.WriteLine(result); } } }