一、文章脉络
二、需要掌握
- 委托、Func、Action的使用
- 简单的Lambda的使用
- EventHandler + WeakEventManager的使用
三、阐述自己学习后的见解
- 委托
- 原理:
- 创建委托,编译器会在后台创建一个类
- 因为是一个类的性质,所以可以写在类可以写的地方:命名空间下、类中
- 因为是一个类的性质,所以是一种自定义的数据类型,是一种引用类型
- 因为是一个类的性质,所以可以加类的修饰符
- 使用:
- 定义:修饰符 + delegate + 方法前面
- 实例化:+= new 对象(方法);
- 调用:对象 + ;
- 作用:
- 传递方法
- 窗体间通信
- 回调方法(A类实例化B,B中调用A的方法)
- 优化代码
- 进阶:
- 掌握Action
- 掌握Func(~~~这两个太方便了,简化了普通委托的代码)
- 原理:
- Lambda
- 原理:
- 一个普通方法签名:返回值 + 函数名 + 参数 + 实现
- 一个匿名方法:一个普通方法前面 Remove 函数名
- Lambda:一个匿名方法在进行简化
- 若只有一个参数,匿名方法的参数可以省掉()
- 若实现只有一行可以省掉实现的{}
- 参数可以不用写类型—>编译器类型推断
- 不用写返回值
- 可以省掉return ————–>由上述可以推出Lambda的本质就是一个方法,编译器会给这个方法起名滴
- simple写法:a=>a;——>传入一个a,返回一个a
- a是什么类型?你传入什么类型就是什么类型,同理你也知道了这样a的参数及返回值 是什么类型
- 与委托的关系:
- 实例化委托需要带入一个方法
- 实例化委托可以带入一个匿名方法
- 实例化委托可以带入一个Lambda
- 好处:
- 可以在一个方法内定义另一个方法
- 如果另一个方法代码很少
- 使用Lambda可以做到优化代码结构的用处
- 如果另一个方法代码很少
- 可以在一个方法内定义另一个方法
- 进阶:
- 闭包:Lambda使用上文定义的局部变量
- C#5.0新的特性,foreach和while会自动产生一个局部变量,保存迭代
- 这是C#5.0和5.0以下分别的方法
- C#5.0新的特性,foreach和while会自动产生一个局部变量,保存迭代
- 闭包:Lambda使用上文定义的局部变量
- 原理:
- EventHandler
- 原理:事件驱动中大量使用,例如Button的Click,如何监听响应,Click的方法参数是不是object sender,EventArgs e
- 微软构造了几百个,拿来直接使用
- 使用:
- Info类,一个发布程序的信息类,继承EventArgs
- BringOut类,发布信息,其中需要一个public event EventHandler,传入的是this,new Info
- Reciver类,订阅发布的信息,里面需要构造一个方法,返回值是void,参数是object sender,Info e
- 代码的事情用文字描述总是感觉苍白,下面给出我模仿后改造的示例代码,很好的明白(一口气写了这么多树杈)
- 弊病:
- GC不会回收发布程序中的引用,使用泛型弱事件管理器WeakmEventManager解决这个问题
- 原理:事件驱动中大量使用,例如Button的Click,如何监听响应,Click的方法参数是不是object sender,EventArgs e
四、值得反复模仿敲打的代码
发布/订阅 + 弱事件处理程序:
/// <summary>
/// 发布程序信息类
/// </summary>
public class SenderInfo : EventArgs //继承该类
{
//发布时间
public DateTime SendTime { get{return DateTime.Now;} }
//发布人姓名
public string SendName { get; set; }
//发布的信息
public string Msg { get; set; }
public SenderInfo()
{
SendName = @"潘鹏";
}
public SenderInfo(string msg)
{
Msg = msg;
}
}
/// <summary>
/// 发布信息
/// </summary>
public class Sender
{
public event EventHandler<SenderInfo> Connector; //提供给订阅者订阅的连接组件
//发布信息
public void SendMsg(string msg)
{
//将要发布的信息告诉推送信息的人
BringOutMsg(msg);
}
//推送信息到各个订阅者
private void BringOutMsg(string msg)
{
if (null != Connector)
Connector(this, new SenderInfo(msg));
}
}
/// <summary>
/// 订阅者
/// </summary>
public class Receiver
{
//订阅信息的结构
public string ReceiveName { get; set; }
public Receiver(string name)
{
ReceiveName = name;
}
/// <summary>
/// 订阅的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e">发布者信息类</param>
public void ReceiveMsg(object sender, SenderInfo e)
{
Console.WriteLine(ReceiveName + "收到:" + e.Msg + " 时间:" + e.SendTime + " 发件人:" + e.SendName);
}
}
static void Main(string[] args)
{
//新建一个发布者
var sender = new Sender();
//新建一个订阅者
var receiver = new Receiver("左转第八办事处");
//订阅者订阅消息
sender.Connector += receiver.ReceiveMsg;
//发布消息
sender.SendMsg("今天总结.NET看书笔记第八章");
//****
//新建一个订阅者
var receiver2 = new Receiver("下水道总署");
//订阅消息
WeakEventManager<Sender, SenderInfo>.AddHandler(sender, "Connector", receiver2.ReceiveMsg);
sender.SendMsg("I dislike coffee");
Console.ReadLine();
}
效果:
刚刚又写了一遍代码,在使用WeakEventManager的时候一直报错,原来只是的平台是.NET4.5及以上~~.~