扣响C#之门笔记---第十六章
16.1 委托
(1)委托使用关键字delegate 申明,它实际上是定义了一种数 据类型(“函数类型”),明确规定了函数的参数类型 和返回值类型,(一般用委托来代替参数,返回值的相同的一类多个函数);

(2)当需要将具体某个函数作为参时候,就先要将它转换为委托的实例;

(3)调用时候,直接将委托实例,传递给定义函数即可;

(4)在新版本的.NET中, 我们可以直接传递函数名称,省去实例化委托的过程;

eg:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test01
{
class Program
{
delegate void AnimalPlay(string name); //(2)为三个函数定义一个委托
static void Run(AnimalPlay a, string name)//(3)定义使用这个三个函数作为参数(委托)的函数
{
a(name);
}
static void DogPlay(string name) //(1)定义三个相同签名的函数 ,函数1
{
Console.WriteLine("Hello,Iam "+name+"!");
Console.WriteLine("****DogPlay****");
}
static void CatPlay(string name) //函数2
{
Console.WriteLine("Hello,Iam " + name + "!");
Console.WriteLine("****CatPlay****");
}
static void LionPlay(string name) //函数3
{
Console.WriteLine("Hello,Iam" + name + "!");
Console.WriteLine("****LionPlay****");
}
static void Main(string[] args)
{
AnimalPlay a = new AnimalPlay(DogPlay);//(4)申明一个委托变量,并实例化;
Run(a, "soopy"); //(5)传递委托实例给函数
Console.ReadKey();
a = new AnimalPlay(CatPlay);
Run(a, "kity");
Console.ReadKey();
}
}
}
16.2 多播委托
(1)可以向一个委托注册多个函数,我们把包含多个函数的委托称为多播委托;(所有被委托的函数都存储在多播委托的调用列列表中,调用多播委托时候,会按顺序依次调用列表中的所有函数(如果一个函数多次注册,就会多次执行));
(2)向多播委托注册函数的语法为:(就是复合运算符+=,等价于a=a+new AnimalPlay(DogPlay))

(3)从多播委托删除函数的语法为:(就是复合运算符-=,等价于a=a- new AnimalPlay(DogPlay))

(4)多播委托的返回值只能为void(如果有返回值,应该返回那个函数的值呢?)
eg:
static void Main(string[] args)
{
AnimalPlay a=null; //申明委托变量
a += new AnimalPlay(DogPlay); //添加注册函数,等价于 a=a+ new AnimalPlay(DogPlay);
a += new AnimalPlay(CatPlay); //添加注册函数
a += new AnimalPlay(LionPlay);//添加注册函数
a -= new AnimalPlay(LionPlay);//删除注册函数等价于 a=a- new AnimalPlay(DogPlay);
Run(a,"");
Console.ReadKey();
}
16.3 匿名函数:
(1) 匿名函数 可以直接直接把“代码块”直接注册给 委托实例,而不需要事先定义函数;
namespace Test03
{
class Program
{
delegate void mydelegate(string s); //(1)定义委托
static void Main(string[] args)
{
mydelegate f = null; //(2)使用匿名函数直接实例化一个委托对象(注意写法)
f = delegate(string s)
{
Console.WriteLine(s);
Console.ReadKey();
};
f("zhangkaineng"); //(3)使用委托
}
}
}
(2)匿名函数不仅可以使用自己方法内部的变量,也可以使用代码块外(宿主函数)定义的变量;
宿主变量被匿名函数使用,称之为宿主变量被匿名函数捕获(被捕获的变量的生存周期将延迟到委托销毁)
eg
namespace Test04
{
class Program
{
delegate void mydelegate(int i,int j ); //定义委托
static void Main(string[] args)
{
int i = 10000; //宿主变量
mydelegate f = null;
f = delegate(int h,int j)
{
Console.WriteLine(i); //使用宿主变量
Console.WriteLine(h);
Console.WriteLine(j);
Console.ReadKey();
};
f(9,8);
}
}
}
16.4 事件
事件就是委托的对象
(1)触发事件的对象称之为事件发送者(EventSender),响应事件的对象称之为事件接收者(EventReceiver)
比如说:按钮就是一个事件发送者,而响应按钮的窗体就是事件的接收者;
(2)事件机制过程与原理:
//(1)事件处理代码 button1_Click private void button1_Click(object sender, EventArgs e) { MessageBox.Show("点击"); } //(2)事件处理代码的委托EventHandler public delegate void EventHandler(object sender, EventArgs e); // (3) 委托的实例对象 事件 Click; public event EventHandler Click; //(4)强事件注册到 事件上 this.button1.Click += new System.EventHandler(this.button1_Click); //(5) 触发事件 mybutton.Click(this,e);
(3)自定义事件
(a)定义被委托函数(处理方法)
(b)定义方法对应的委托
(c)定义委托对应的对象(即事件)
(d)将被委托的函数注册到委托对象(事件上)
(f)引发事件
class Program { static void Main(string[] args) { dog d = new dog(); host h = new host(d); d.OnAlam(); Console.ReadKey(); } } class dog { //(2)定义方法对应的委托 public delegate void AlarmHander(object sender, EventArgs e); //(3)定义委托对应的对象(即事件) public AlarmHander Alam; //(5)引发事件 public void OnAlam() { this.Alam(this,new EventArgs()); } int i; } class host { // (1)定义被委托函数(处理方法) public void HostAlm(object sender, EventArgs e) { Console.WriteLine("抓住小偷"); } //(4)将被委托的函数注册到委托对象(事件上) public host(dog d) { d.Alam += new dog.AlarmHander(HostAlm); } int i; }
(4)C#定义了100多个事件参数类,他们都继承于EventArgs
(5)可以重新定义EventArgs 类,此类可用于 事件触发者向订阅者 传递参数
class Program { static void Main(string[] args) { dog d = new dog(); host h = new host(d); d.dogjok(2); Console.ReadKey(); } } //(1)C#定义了100多个事件参数类,他们都继承于EventArgs //(2)可以重新定义EventArgs 类,此类可用于 事件触发者向订阅者 传递参数 public class AlamEventArgs:EventArgs { public int number; public AlamEventArgs(int i) { this.number = i; } } class host { //将传递过来的参数取出使用 public void hosthand(object o,AlamEventArgs e) { if (e.number < 2) { Console.WriteLine("抓住住小偷"); } else Console.WriteLine("人太多 报警"); } public host(dog d) { d.alm += new dog.hosthander(hosthand); } } class dog { public delegate void hosthander (object o,AlamEventArgs e); public event hosthander alm; public void dogjok(int i) //触发者产生参数i 通过构造函数将此值保存到EventArgs对象中 { alm(this, new AlamEventArgs(i)); } }
浙公网安备 33010602011771号