《C#高级教程》学习笔记13

第二十天
(即使没人看,还要继续写,这样才有动力学习)

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)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值