[读书笔记]C#学习笔记二: 委托和事件的用法及不同.
前言:
C#委托是什么
c#中的委托可以理解为函数的一个包装, 它使得C#中的函数可以作为参数来被传递, 这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址, 然后通过这个指针来实现对函数的操作.
委托的定义和方法的定义类似, 只是在定义的前面多了一个delegate关键字.
正文:
委托可以被视为一个更高级的指针,它不仅仅能把地址传指向另一个函数,而且还能传递参数,返回值等多个信息。
系统还为委托对象自动生成了同步,异步的调用方式,开发人员使用BeginInvoke,EndInvoke方法就可以抛开Thread而直接使用多线程调用。
一, 委托
用IL 分析可看出Delegate继承自System.MulticastDelegate类,并自动生成BeginInvoke,EndInvoke,Invoke三种常见的方法。
Invoke方法是用于同步调用委托对象的对应方法,而BeginInvoke,EndInvoke是用于以异步方式调用对应方法的。
1.1 简单的委托
当建立委托对象时,委托的参数类型必须与委托方法相对应。只要向建立委托对象的构造函数中输入方法名称example.Method,委托就会直
接绑定此方法。
使用myDelegate.Invoke(string message),就能显式调用委托方法。
但在实际的操作中,我们无须用到 Invoke 方法,而只要直接使用myDelegate(string message),就能调用委托方法。
class Program
{
void MyDelegate(string message); public class Example
{
public void Method(string message)
{
MessageBox.Show(message);
}
} static void Main(string[] args)
{
Example example=new Example();
MyDelegate myDelegate=new MyDelegate(example.Method);
myDelegate("Hello World");
Console.ReadKey();
}
}
1.2 带返回值的委托
当建立委托对象时,委托的返回值必须与委托方法相对应。使用下面的例子,方法将返回 “Hello Leslie” 。
class Program
{
delegate string MyDelegate(string message); public class Example
{
public string Method(string name)
{
return "Hello " + name;
}
} static void Main(string[] args)
{
Example example=new Example();
//绑定委托方法
MyDelegate myDelegate=new MyDelegate(example.Method);
//调用委托,获取返回值
string message = myDelegate("Leslie");
Console.WriteLine(message);
Console.ReadKey();
}
}
1.3 多路广播委托
在上面提过,委托类继承于MulticastDelegate,这使委托对象支持多路广播,即委托对象可以绑定多个方法。
当输入参数后,每个方法会按顺序进行迭代处理,并返回最后一个方法的计算结果。
下面的例子中,Price 类中有两个计算方法,Ordinary 按普通的9.5折计算,Favourable 按优惠价 8.5 折计算。
委托同时绑定了这两个方法,在输入参数100以后,Ordinary、Favourable这两个方法将按顺序迭代执行下去,最后返回 Favourable 方法的
计算结果 85。
delegate double MyDelegate(double message);
public class Price
{
public double Ordinary(double price)
{
double price1 = 0.95 * price;
Console.WriteLine("Ordinary Price : "+price1);
return price1;
} public double Favourable(double price)
{
double price1 = 0.85 * price;
Console.WriteLine("Favourable Price : " + price1);
return price1;
} static void Main(string[] args)
{
Price price = new Price();
//绑定Ordinary方法
MyDelegate myDelegate = new MyDelegate(price.Ordinary);
//绑定Favourable方法
myDelegate += new MyDelegate(price.Favourable);
//调用委托
Console.WriteLine("Current Price : " + myDelegate());
Console.ReadKey();
}
}
1.4 Observer模式中的事件与委托
class Program
{
public delegate void ObserverDelegate(); static void Main(string[] args)
{
// 具体主题角色通常用具体自来来实现
ConcreteSubject subject = new ConcreteSubject(); //传入的只是观察者的通过方法。
subject.Attach(new ConcreteObserver(subject, "Observer A").Update);
subject.Attach(new ConcreteObserver(subject, "Observer B").Update);
subject.Attach(new ConcreteObserver(subject, "Observer C").Update); subject.SubjectState = "Ready";
subject.Notify(); Console.Read();
} //抽象主体类
public abstract class Subject
{
public ObserverDelegate observerDelegate; //增加观察者
public void Attach(ObserverDelegate observer)
{
observerDelegate += observer;
} //移除观察者
public void Remove(ObserverDelegate observer)
{
observerDelegate -= observer;
} //像观察者发通知
public void Notify()
{
if (observerDelegate != null)
{
observerDelegate();
}
}
} //具体主题类
public class ConcreteSubject : Subject
{
public string SubjectState { get; set; }
} //具体观察者
public class ConcreteObserver
{
private string observerState;
private string name;
private ConcreteSubject subject; public ConcreteObserver(ConcreteSubject subject, string name)
{
this.subject = subject;
this.name = name;
} //实现抽象观察者中的更新操作
public void Update()
{
observerState = subject.SubjectState;
Console.WriteLine("The observer's state of {0} is {1}", name, observerState);
}
}
}
二,事件 event
(1) 事件时委托的封装,可以理解为一种特殊的委托。
(2) 事件里面其实就两个方法(即add_event() 和 remove_event())和一个私有的委托变量,这两个方法里面分别是对这个私有的委托变量进
行的合并和移除,当调用事件的+=时其实是调用的事件里的add_event()方法,同样-=调用的是remove_event()方法
(3) 事件只能够从对象外部增加新的响应方法和删除已知的响应方法,而不能主动去触发事件和获取其他注册的响应方法等信息。如果使用
公有的delegate则不能做这些限制,也就是说事件对委托做了限制,使委托使用起来更加方便。
也有人说事件是对委托的阉割,大概也是这个意思。
这里事件没有做过多的阐述, 看到一个关于事件讲解的比较不错的博文, 推荐大家看下吧: http://www.cnblogs.com/landeanfen/p/4721525.html
PS: 本博客只是为了记录自己学习中的收获, 俗话说 好记性不如烂笔头. 望自己能够坚持下去.
[读书笔记]C#学习笔记二: 委托和事件的用法及不同.的更多相关文章
- [读书笔记]C#学习笔记一: .Net Framwork
前言: 一次偶然的机会 在园子里看到@Learning hard 出版的一本书: <<C#学习笔记>>, 然后买来 一直到现在读完, 感觉很不错, 适合入门, 书中内容是从C ...
- [读书笔记]C#学习笔记三: C#类型详解..
前言 这次分享的主要内容有五个, 分别是值类型和引用类型, 装箱与拆箱,常量与变量,运算符重载,static字段和static构造函数. 后期的分享会针对于C#2.0 3.0 4.0 等新特性进行. ...
- [读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析
前言 上次在公司开会时有同事分享windebug的知识, 拿的是string字符串Concat拼接 然后用while(true){}死循环的Demo来讲解.其中有提及string操作大量字符串效率低下 ...
- [读书笔记]C#学习笔记四: C#2.0泛型 可控类型 匿名方法和迭代器
前言 C#1.0的委托特性使方法作为其他方法的参数来传递,而C#2.0 中提出的泛型特性则使类型可以被参数化,从而不必再为不同的类型提供特殊版本的实现方法.另外C#2.0还提出了可空类型,匿名方法和迭 ...
- C#学习笔记(四):委托和事件
刚开始学习C#的时候就写过了,直接给地址了: 委托.匿名函数.Lambda表达式和事件的学习 委托学习续:Action.Func和Predicate
- 《Inside C#》笔记(十二) 委托与事件
C#的委托与C++的函数指针类似,但委托是类型安全的,意味着指针始终会指向有效的函数.委托的使用主要有两种:回调和事件. 一 将委托作为回调函数 在需要给一个函数传递一个函数指针,随后通过函数指针调用 ...
- [读书笔记]C#学习笔记七: C#4.0中微小改动-可选参数,泛型的可变性
前言 下面就开始总结C#4.0的一些变化了, 也是这本书中最后的一点内容了, 这一部分终于要更新完了. 同时感觉再来读第二遍也有不一样的收获. 今天很嗨的是武汉下雪了,明天周六,一切都是这么美好.哈哈 ...
- [读书笔记]C#学习笔记六: C#3.0Lambda表达式及Linq解析
前言 最早使用到Lambda表达式是因为一个需求:如果一个数组是:int[] s = new int[]{1,3,5,9,14,16,22};例如只想要这个数组中小于15的元素然后重新组装成一个数组或 ...
- C#学习笔记(十七):委托、事件、观察者模式、匿名委托和lambert表达式
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
随机推荐
- centos7 ip地址设置
centos7 ip地址设置 http://simonhu.blog.51cto.com/196416/1588971 CentOS系统 修改DNS 修改对应网卡的DNS的配置文件 # vi /etc ...
- 2014 ACM/ICPC 北京邀请赛 部分 题解
题目链接:http://acm.bnu.edu.cn/bnuoj/problem.php?search=2014+ACM-ICPC+Beijing+Invitational+Programming+C ...
- 禅道Linux一键安装版
禅道Linux一键安装版 Linux一键安装包内置了apache, php, mysql这些应用程序,只需要下载解压缩即可运行禅道.从7.3版本开始,linux一键安装包分为32位和64位两个包,大家 ...
- ceph初步快速部署
一.基本情况:物理设备:4台惠普dl360,4个千兆网卡 4个1T盘操作系统统一为:CentOS 7.2.1511ceph版本:10.2.3ceph-deploy版本:1.5.36网络情况:192.1 ...
- max10中对DDR数据的采样转换
(1)发现IP是这样处理DDR的数据:上长沿采的数据放在低位,下降沿采的数据在高位 (2)对于视频的行场信号是在下降沿采集,再延时一拍才能与数据对齐.
- MRP生产计划模式在多品种小批量生产过程中遭遇挑战
传统的MPS主生产计划和MRP物料需求计划的方式,已很难适应按需生产环境,很多企业正在转向按需生产环境,按需生产的最大的挑战是模拟计算CTP可以承诺交期.准时交货和应对不确定的插单等变化.不仅需要订单 ...
- NGUI 便捷的显示与隐藏界面
所有的UI都继承自class UIBase,可以把UI做成预设体,同个场景下,读取预设体时,将子UI对象都保存在类似Dictionary<UIType, UIBase>这样的结构中,这样的 ...
- linux学习之——基础命令
Linux体系基础命令: Linux是一个命令行组成的操作体系!精华在命令行,岂论图形界面成长到什么水平这个原理是不会变的,Linux命令有许多壮大的效用:从简单的磁盘操作.文件存取.到举办庞大的多媒 ...
- [原创] Legato 8.1 oracle full backup skip 奇怪的问题处理过程 -- 非调度日期手工运行调度也不成功(skip)
转载请注明出处: http://www.cnblogs.com/fengaix6/p/4677024.html 作者:飄ぺ風 环境: a. Server: Legato 8.1.2, aix 6.1 ...
- SQL中的循环、for循环、游标
我们使用SQL语句处理数据时,可能会碰到一些需要循环遍历某个表并对其进行相应的操作(添加.修改.删除),这时我们就需要用到咱们在编程中常常用的for或foreach,但是在SQL中写循环往往显得那么吃 ...