第二十天
(即使没人看,还要继续写,这样才有动力学习)
8.4事件
事件基于委托,为委托提供了一种发布/订阅机制。
using System;
namespace W{
public class CarInfoEventArgs:EventArgs{
public CarInfoEventArgs(string car){
this.Car=car;
}
public string Car{get;private set;}
}
public class CarDealer{
public event EventHandler<CarInfoEventArgs> NewCarInfo;
public void NewCar(string car){
Console.WriteLine("CarDealer,new car {0}",car);
RaiseNewCarInfo(car);
}
protected virtual void RaiseNewCarInfo(string car){
EventHandler<InfoEventArgs> newCarInfo=NewCarInfo;
if(newCarInfo!=null){
newCarInfo(this,new CarInfoEventArgs(car));
}
}
}
}
CarDealer类用event关键字定义了类型为EventHandler<CarInfoEventArgs>的NewCarInfo事件。
在NewCar()方法中,通过调用RaiseNewCarInfo方法触发NewCarInfo事件。
作为一个约定,事件一般使用带两个参数的方法,其中一个参数是一个对象,包含事件的发送者,第二个参数提供了事件的相关信息。第二个参数随不同的事件类型不同。
EventHandler<TEventArgs>定义了一个处理程序,它返回void,接受两个参数。对于第一个参数必须是object类型,第二个参数是T类型。EventHandler<TEventArgs>还定义了一个关于T的约束:它必须派生自基类EventArgs,CarInfoEventArgs就派生自基类EventArgs
委托EventHandler<TEventArgs>的定义如下:
public delegate void EventHander<TEventArgs>(object sender,TEventArgs e)where TEventArgs:EventArgs
上面是简化记法
下面是较长形式:
private delegate EventHandler<CarInfoEventArgs> newCarInfo;
public event EventHandler<CarInfoEventArgs> NewCarInfo{
add{
newCarInfo+=value;
}
remove{
newCarInfo-=value;
}
}
8.4.2事件侦听器
下面类用作事件侦听器:
using System;
namespace W{
public class Consumer{
private string name;
public Consumer(String name){
this.name=name;
}
public void NewCarIsHere(object sender,CarInfoEventArgs s){
Console.WriteLine("{0}:car {1} is new",name,e.Car);
}
}
}
现在需要连接事件发布程序和订阅器。
namespace W{
class Program{
static void Main(){
var dealer=new CarDealer();
var michael=new Consumer("Michael");
dealer.NewCarInfo+=michael.NewCarIsHere;
dealer.NewCar("Ferrari");
var sebastian=new Consumer("Sebastian");
dealer.NewCarInfo+=sebastian.NewCarIsHere;
dealer.NewCar("Mercedes");
dealer.NewCarInfo-=michael.NewCarIsHere;
dealer.NewCar("Red Bull Racing");
}
}
}
运行程序,一辆Ferrair到达,Micheal得到了通知。因为之后Sebastian也注册了该订阅,所以Micheal和Sebastian都获得了新的Mercedes的通知。接着Michael取消了订阅,所以只有Sebastian获得了Red Bull的通知。
8.4.3弱事件
通过事件,直接连接到发布程序和侦听器。但垃圾回收有一个问题。
例如,如果侦听器不再直接引用,发布程序仍有一个引用。垃圾回收器不能清空侦听器占用的内存,因为发布程序仍保有一个引用,会针对侦听器触发事件。
这种强连接可以通过弱事件模式来解决,即使用WeakEventManager作为发布程序和侦听器之间的中介。
using System.Window;
namespace W{
public class WeakCarInfoEventManager:WeakEventManager{
public static void AddListener(object source,IWeakEventListener listener){
CurrentManager.ProtectedAddListener(source,listener);
}
public static void RemoveListener(object source,listener){
CurrentManager.ProtectedRemoveListener(source,listener);
}
public static WeakCarInfoEventManager CurrentManager{
get{
var manager=GetCurrentManager(typeof(WeakCarInfoEventManager)) as WeakCarInfoEventManager;
if(manager==null){
manager=new WeakCarInfoEventManager();
SetCurrentManager(typeof(WeakCarInfoEventManager),manager);
}
return manager;
}
}
protected override void StartListening(object source){
(source as CarDealer).NewCarInfo+=CarDealer_NewCarInfo;
}
void CarDealer_NewCarInfo(object sender,CarInfoEventArgs e){
DeliverEvent(sender,e);
}
protected override void StopListening(object source){
(source as CarDealer).NewCarInfo=CarDealer_NewCarInfo;
}
}
}
WeakCarInfoEventManager类是弱事件管理类,它管理NewCarInfo事件的发布程序和侦听器之间的连接。因为这个类实现了单态模式,所以只创建一个实例。(哦哦哦,单态模式,以前见过,好帅啊)
对于弱事件模式,弱事件管理器类需要静态方法AddListener()和RemoveListener()。侦听器使用这些方法连接发布程序,断开与发布程序的连接,而不是直接使用发布程序的事件。
对于WeakCarInfoEventManager类,还需要重写基类的StartListener()和StopListener()方法,添加第一个侦听器时调用StartListener()方法,删除最后一个侦听器时调用StopListener()方法。StartListener()方法和StopListener()方法从弱事件管理中订阅和取消订阅一个方法,以侦听发布程序中的事件。
2事件侦听器
using System;
using System.Windows;
namespace W{
public class Constumer:IWeakEventListener{
private string name;
public Constumer(string name){
this.name=name;
}
public void NewCarIsHere(object sender,CarInfoEventArgs e){
Console.WriteLine("{0}: car {1} is new",name,e.Car);
}
bool IWeakEventListener.ReceiveWeakEvent(Type managerType,object sender,EventArgs e){
NewCarIsHere(sender,e as CarInfoEventArgs);
return true;
}
}
}
Main方法
static void Main(){
var dealer=new CarDealer();
var michael=new Consumer("Michael");
WeakCarInfoEventManager.Addlistener(dealer,michael);
dealer.NewCar("Mercedes");
var sebastian=new Consumer("Sebastian");
WeakCarInfoEventManager.AddListener(dealer,sebastian);
dealer.NewCar("Ferriari");
WeakCarInfoEventManager.RemoveListener(dealer.michael);
dealer.NewCar("Red Bull Racing");
}
3泛型事件管理器
泛型类WeakEventManager<TEventSource,TEventArgs>派生自基类,显著简化了弱事件的处理。使用这个类时,不再需要为每个事件实现一个自定义的弱事件管理器,也不需要让事件的消费者实现接口IWeakEventListener。所要做的就是使用泛型弱事件管理器订阅事件。
第九章
字符串和正则表达式
C#的string关键字映射.NET的基类System.String
9.1 System.String类
里面有一堆方法,这里略
9.1.1创建字符串
string的字符串其实是不可变的数据类型,平时进行操作都是建立在新建另一个字符串之上,而原来的被垃圾回收器回收掉
String类里有一个Replace(),用这个对一个一个字符进行操作耗大量时间与内存
解决方法:使用System.Text.StringBuilder类,
在System.Text.StringBuilder类上进行的处理仅限于替换和追加或删除字符串中的文本。但是它的工作方式非常高效。
StringBuilder类通常分配的内存会比它需要的多,开发人员可指定分配给它的内存。
主要的两个属性:
Length指定字符串的实际长度。
Capacity指定字符串在分配的内存中的最大长度。
StringBuilder s=new StringBuilder("HelloWrold",150);
如果超出的话,会自动翻倍。
理论允许最大空间是20亿个字符,但系统可能会没有足够内存。
9.1.2 StringBuilder成员
Append() 给当前字符串追加一个字符串
AppendFormat() 追加特定格式的字符串
Insert() 在当前字符串中插入一个子字符串
Remove() 在当前字符串删除字符
Replace() 在当前字符串中,用某个字符全部替换另一个字符,或者用当前字符串的一个子字符串全部替换成另一个字符串
ToString() 返回当前强制转换为System.String对象的字符串(在System.Object中重写)
(2014.12.22)
(即使没人看,还要继续写,这样才有动力学习)
8.4事件
事件基于委托,为委托提供了一种发布/订阅机制。
using System;
namespace W{
public class CarInfoEventArgs:EventArgs{
public CarInfoEventArgs(string car){
this.Car=car;
}
public string Car{get;private set;}
}
public class CarDealer{
public event EventHandler<CarInfoEventArgs> NewCarInfo;
public void NewCar(string car){
Console.WriteLine("CarDealer,new car {0}",car);
RaiseNewCarInfo(car);
}
protected virtual void RaiseNewCarInfo(string car){
EventHandler<InfoEventArgs> newCarInfo=NewCarInfo;
if(newCarInfo!=null){
newCarInfo(this,new CarInfoEventArgs(car));
}
}
}
}
CarDealer类用event关键字定义了类型为EventHandler<CarInfoEventArgs>的NewCarInfo事件。
在NewCar()方法中,通过调用RaiseNewCarInfo方法触发NewCarInfo事件。
作为一个约定,事件一般使用带两个参数的方法,其中一个参数是一个对象,包含事件的发送者,第二个参数提供了事件的相关信息。第二个参数随不同的事件类型不同。
EventHandler<TEventArgs>定义了一个处理程序,它返回void,接受两个参数。对于第一个参数必须是object类型,第二个参数是T类型。EventHandler<TEventArgs>还定义了一个关于T的约束:它必须派生自基类EventArgs,CarInfoEventArgs就派生自基类EventArgs
委托EventHandler<TEventArgs>的定义如下:
public delegate void EventHander<TEventArgs>(object sender,TEventArgs e)where TEventArgs:EventArgs
上面是简化记法
下面是较长形式:
private delegate EventHandler<CarInfoEventArgs> newCarInfo;
public event EventHandler<CarInfoEventArgs> NewCarInfo{
add{
newCarInfo+=value;
}
remove{
newCarInfo-=value;
}
}
8.4.2事件侦听器
下面类用作事件侦听器:
using System;
namespace W{
public class Consumer{
private string name;
public Consumer(String name){
this.name=name;
}
public void NewCarIsHere(object sender,CarInfoEventArgs s){
Console.WriteLine("{0}:car {1} is new",name,e.Car);
}
}
}
现在需要连接事件发布程序和订阅器。
namespace W{
class Program{
static void Main(){
var dealer=new CarDealer();
var michael=new Consumer("Michael");
dealer.NewCarInfo+=michael.NewCarIsHere;
dealer.NewCar("Ferrari");
var sebastian=new Consumer("Sebastian");
dealer.NewCarInfo+=sebastian.NewCarIsHere;
dealer.NewCar("Mercedes");
dealer.NewCarInfo-=michael.NewCarIsHere;
dealer.NewCar("Red Bull Racing");
}
}
}
运行程序,一辆Ferrair到达,Micheal得到了通知。因为之后Sebastian也注册了该订阅,所以Micheal和Sebastian都获得了新的Mercedes的通知。接着Michael取消了订阅,所以只有Sebastian获得了Red Bull的通知。
8.4.3弱事件
通过事件,直接连接到发布程序和侦听器。但垃圾回收有一个问题。
例如,如果侦听器不再直接引用,发布程序仍有一个引用。垃圾回收器不能清空侦听器占用的内存,因为发布程序仍保有一个引用,会针对侦听器触发事件。
这种强连接可以通过弱事件模式来解决,即使用WeakEventManager作为发布程序和侦听器之间的中介。
using System.Window;
namespace W{
public class WeakCarInfoEventManager:WeakEventManager{
public static void AddListener(object source,IWeakEventListener listener){
CurrentManager.ProtectedAddListener(source,listener);
}
public static void RemoveListener(object source,listener){
CurrentManager.ProtectedRemoveListener(source,listener);
}
public static WeakCarInfoEventManager CurrentManager{
get{
var manager=GetCurrentManager(typeof(WeakCarInfoEventManager)) as WeakCarInfoEventManager;
if(manager==null){
manager=new WeakCarInfoEventManager();
SetCurrentManager(typeof(WeakCarInfoEventManager),manager);
}
return manager;
}
}
protected override void StartListening(object source){
(source as CarDealer).NewCarInfo+=CarDealer_NewCarInfo;
}
void CarDealer_NewCarInfo(object sender,CarInfoEventArgs e){
DeliverEvent(sender,e);
}
protected override void StopListening(object source){
(source as CarDealer).NewCarInfo=CarDealer_NewCarInfo;
}
}
}
WeakCarInfoEventManager类是弱事件管理类,它管理NewCarInfo事件的发布程序和侦听器之间的连接。因为这个类实现了单态模式,所以只创建一个实例。(哦哦哦,单态模式,以前见过,好帅啊)
对于弱事件模式,弱事件管理器类需要静态方法AddListener()和RemoveListener()。侦听器使用这些方法连接发布程序,断开与发布程序的连接,而不是直接使用发布程序的事件。
对于WeakCarInfoEventManager类,还需要重写基类的StartListener()和StopListener()方法,添加第一个侦听器时调用StartListener()方法,删除最后一个侦听器时调用StopListener()方法。StartListener()方法和StopListener()方法从弱事件管理中订阅和取消订阅一个方法,以侦听发布程序中的事件。
2事件侦听器
using System;
using System.Windows;
namespace W{
public class Constumer:IWeakEventListener{
private string name;
public Constumer(string name){
this.name=name;
}
public void NewCarIsHere(object sender,CarInfoEventArgs e){
Console.WriteLine("{0}: car {1} is new",name,e.Car);
}
bool IWeakEventListener.ReceiveWeakEvent(Type managerType,object sender,EventArgs e){
NewCarIsHere(sender,e as CarInfoEventArgs);
return true;
}
}
}
Main方法
static void Main(){
var dealer=new CarDealer();
var michael=new Consumer("Michael");
WeakCarInfoEventManager.Addlistener(dealer,michael);
dealer.NewCar("Mercedes");
var sebastian=new Consumer("Sebastian");
WeakCarInfoEventManager.AddListener(dealer,sebastian);
dealer.NewCar("Ferriari");
WeakCarInfoEventManager.RemoveListener(dealer.michael);
dealer.NewCar("Red Bull Racing");
}
3泛型事件管理器
泛型类WeakEventManager<TEventSource,TEventArgs>派生自基类,显著简化了弱事件的处理。使用这个类时,不再需要为每个事件实现一个自定义的弱事件管理器,也不需要让事件的消费者实现接口IWeakEventListener。所要做的就是使用泛型弱事件管理器订阅事件。
第九章
字符串和正则表达式
C#的string关键字映射.NET的基类System.String
9.1 System.String类
里面有一堆方法,这里略
9.1.1创建字符串
string的字符串其实是不可变的数据类型,平时进行操作都是建立在新建另一个字符串之上,而原来的被垃圾回收器回收掉
String类里有一个Replace(),用这个对一个一个字符进行操作耗大量时间与内存
解决方法:使用System.Text.StringBuilder类,
在System.Text.StringBuilder类上进行的处理仅限于替换和追加或删除字符串中的文本。但是它的工作方式非常高效。
StringBuilder类通常分配的内存会比它需要的多,开发人员可指定分配给它的内存。
主要的两个属性:
Length指定字符串的实际长度。
Capacity指定字符串在分配的内存中的最大长度。
StringBuilder s=new StringBuilder("HelloWrold",150);
如果超出的话,会自动翻倍。
理论允许最大空间是20亿个字符,但系统可能会没有足够内存。
9.1.2 StringBuilder成员
Append() 给当前字符串追加一个字符串
AppendFormat() 追加特定格式的字符串
Insert() 在当前字符串中插入一个子字符串
Remove() 在当前字符串删除字符
Replace() 在当前字符串中,用某个字符全部替换另一个字符,或者用当前字符串的一个子字符串全部替换成另一个字符串
ToString() 返回当前强制转换为System.String对象的字符串(在System.Object中重写)
(2014.12.22)