前言: 在我们学习C#的过程中,我们会学习到C#委托和事件,由于这是C#中比较高级的内容,所以学起来相当的费力,没有一定的时间是体验不来的,正好我这几天在学这个知识点,所以做一个小总结,希望和我一样的童鞋们能够参考一下,我们共同进步!,此博客属于学习笔记,写的不好,还请见谅!
1. 委托的定义
(1) 将方法作为变量使用的一种机制,就是将方法当作变量用(声明,赋值,传参)
(2) 将变量当作方法来用,首先就要去声明变量,就要考虑变量的类型,就是(委托变量,对应方法的返回值,参数等),顾名思义:委托就是委托别人去干某些事情,下面是一个实例方法的实现
例如:我现在饿了,但是我很懒,就是不想出去买,所以这时候我可以委托室友帮我带一份,这样我就已经实现委托了,
如果我想去吃饭的话实现的代码是:
class Program { static void Main(string[] args) { chum ch = new chum(); ch.EatFood(); Console.ReadKey(); } } class chum { public void EatFood() { Console.WriteLine("我要去吃饭了!"); } }
但是我今天很懒,我要在宿舍睡觉,所以我委托别人带,这样实现代码就是
//定义委托
public delegate void EatFootDelegate(); class Program { static void Main(string[] args) { chum ch = new chum(); //这个地方就是授权,因为委托已经定义了这个委托类型可以使用什么方法 //直接为变量赋值就可以了,赋值的时候使用方法名(不要括号) EatFootDelegate leadfood = ch.EatFood; //此时我的室友就等同于我买吃的东西的方法了 leadfood(); Console.ReadKey(); } } class chum { public void EatFood() { Console.WriteLine("我要去吃饭了!"); } }
最后将这几点做个总结如下:
(1)使用委托,就是需要有一个变量来指向这个方法
(2)定义一个委托类型的变量,先要定义一个委托(这个委托规定了可以赋值方法的信息)
(3)语法:delegate 方法返回类型 委托类型名(方法可用参数)
(4)委托就是一个类型
(5)使用委托就是让方法可以当成变量用
1) 弄清楚那些方法需要当作变量用
2) 根据方法的返回值和类型定义委托类型
3) 声明委托类型的变量
4) 初始化委托变量(就是赋值)
5) 此时这个委托变量就是等价于方法了,使用委托变量加圆括号就是在调用指定的那个方法
6) 既然是变量,就可以通过参数传递等其他方式使用了
2. 静态方法实现委托
(1)委托变量在指向方法的时候,就是"相当于"存放着方法的地址,在调用的时候直接到内存中找到方法代码,执行
(2) 既然委托只是存储方法,就不需要理会这个方法是什么类型的(静态还是实例的)
(3)实现调用方法的时候就是直接为其赋值即可
public delegate void FuncDelegate(); class Program { static void Main(string[] args) { FuncDelegate func = SayHello; func(); Console.ReadKey(); } static void SayHello() { Console.WriteLine("我是一个静态方法"); } }
(4)如果没有为委托变量赋值,那么会抛出异常(因为委托变量是null)
FuncDelegate func = null;
func();
这样但在执行的时候会抛出异常"未将对象引用到对象的实例"
(5)委托是具有面向对象特征的,所以你也可以new出对象
public delegate void FuncDelegate(); class Program { static void Main(string[] args) { FuncDelegate func = new FuncDelegate(SayHello); func(); Console.ReadKey(); } static void SayHello() { Console.WriteLine("我是一个静态方法"); } }
(6)委托在使用的时候,由于委托变量指的就是方法,所以一般给委托变量命名使用Pascal命名规则
(7)委托是一个类(与指针的区别)
(8)自己定义的委托来自于MulticastDalagete类型,而Multicastdatagete有来自于Delegate类型
3. Invoke
(1)委托变量作为方法进行进行调用执行,其本质就是Ivoke方法实现的
FuncDelegate func=Function;
func()等价于 func.Invoke(),下面代码说明了这点
public delegate void FuncDelegate(); class Program { static void Main(string[] args) { FuncDelegate func = Show; func.Invoke(); Console.ReadKey(); } public static void Show() { Console.WriteLine("Invoke"); } }
4. 实例方法和静态方法在执行时的一点小区别
(1)因为实例方法包含实例的成员,所以执行的时候我们设置断点可以查看一下这个简单的方法的执行结果,代码:
public delegate void FuncDelegate(); class Program { static void Main(string[] args) { Person p = new Person() { Name = "张三" }; FuncDelegate func = new FuncDelegate(p.sayHello); FuncDelegate funcstatic = new FuncDelegate(show); func(); funcstatic(); Console.ReadKey(); } public static void show() { Console.WriteLine("show"); } } class Person { public string Name { get; set; } public void sayHello() { Console.WriteLine(Name); } }
下面的章节还会详细介绍委托和事件的