委托与事件
? 委托是调用函数的一种机制
有的书中也将其翻译为代理或代表。
C#中没有指针,C#通过委托实现函数指针的功能。 与函数指针不同,委托是面向对象的。
? 事件是类在发生某件事情时提供通知的一种机制。 用户可以通过事件句柄来为事件添加可执行代码。
一个事件声明的类型必须是一个委托类型,而那个委托类型必须可访问 委托 class Prgram {
private static MyDelegate mydele; public static void f(int n) {
Console.WriteLine(n); }
static void Main(string[] args) {
mydele = new MyDelegate(f); mydele(555); Console.WriteLine( ); Console.Read(); } }
delegate void MyDelegate(int i); 含义
委托是引用类型,派生于System.Delegate类。
委托类型隐含为密封的,即不能从委托类型派生任何类。 也不能从System.Delegate类派生一个非委托类型。 方法的签名和委托的签名相匹配。
委托的实现
分为3步:类型声明、实例化和调用
委托的声明与函数类似,但不含有执行代码,而且要使用delegate关键字。 delegate double myDelegate(double d);
用一个委托响应多个方法 ? 委托有两种类型:
单一委托和多委托
多委托的返回类型必须是void,即不能有返回值 ? 将多个方法赋值给委托的方法 使用+=运算符
相应地,使用-=运算符可以从多委托中删除某个方法
multiDelegate mDelegate;
mDelegate = new multiDelegate(first); mDelegate += new multiDelegate(second); public static void first()
{ Console.WriteLine(\ }
public static void second( ) {
Console.WriteLine(\ }
delegate void Dlgt(); static void Main(string[] args) {
Dlgt dlgt;
dlgt= new Dlgt(first); dlgt+=new Dlgt(second); dlgt();
Console.Read(); } 事件
? 事件含义
是向对像和类提供通知的类成员。 一个类通过事件声明来定义一个事件
声明方法:用event关键字,类型必须是delegate类型 ? 事件的处理过程
(1)应用程序创建一个可以引发事件的对象。
单一委托可以有返回值。
例如,按钮的单击事件,首先需要创建一个按钮,当用鼠标单击该按钮时,
这会引发按钮的Click事件。 (2)应用程序订阅事件。
定义一个函数,该函数与事件相关联。 (3)引发事件后,就调用相应的事件处理函数。 public delegate void eventhandler(string strText); class Eventsource
{ public event eventhandler TextOut; public void TriggerEvent() {TextOut(\ }
class Program
{ static void Main(string[] args) {
Eventsource evsrc=new Eventsource(); evsrc.TextOut+=new eventhandler(CatchEvent); evsrc.TriggerEvent(); }
public static void CatchEvent(string strText) { Console.WriteLine(strText);Console.Read(); } } 响应定时器事件
.NET框架提供了3个定时器(Timer)类: 1、在System.Windows.Forms命名空间中。
该类通常应用在窗体应用程序中,也被用来实现定时器控件 程序员可以以添加控件的形式创建该例的实例。
2、System.Threading.Timer类,主要是在自身的线程中进行操作。 3、System.Timer.Timer类,它为多线程运行环境提供通用的定时器。 例题
static int count;
static Timer t = new Timer(1000); static void Main(string[] args) {
t.AutoReset = true;
t.Elapsed+=new ElapsedEventHandler(myeventf); t.Start(); Console.Read(); } static
void
myeventf(object
obj,ElapsedEventArgs
e)
{ Console.WriteLine(e.SignalTime.ToString()); if (count-- == 0) t.Close(); }
? t.AutoReset获取或设置一个值,该值指示 Timer 是应在每次指定的间隔
结束时引发 Elapsed 事件,还是仅在指定的间隔第一次结束后引发该事件。
? 如果 Timer 应在每次间隔结束时引发 Elapsed 事件,则为 true; 如果它仅在间隔第一次结束后引发一次 Elapsed 事件,则为 false 默认为 true。 集合与索引
? 提供集合功能的接口 ? 使用集合 ? 定义集合 ? 索引
提供集合功能的接口
? 集合类用于处理对象列表,其功能比数组要多,集合元素的数目可以变化。 ? 实现方法分成两种:利用现成的集合类、自定义集合类
? 为了完成集合功能,在System.Collections命名空间中提供了许多接口:
? IEnumerable可以迭代集合中的项。
? ICollection (继承于IEnumerable)可以获取集合中项的个数,并能把
项复制到一个简单的数组类型中。
? IList (继承于IEnumerable和ICollection)提供了集合的项列表,并
可以访问这些项,以及其他一些与项列表相关的功能。
? IDictionary (继承于IEnumerable 和ICollection)类似于IList,但提
供了可通过键码值而不是索引访问的项列表。
使用集合
System.Collections命名空间中的System.Collections.ArrayList类也实现了IList、ICollection和IEnumerable接口,但实现的方式比System.Array更复杂。
数组的大小是固定的(不能增加或删除元素),而这个类可以用于表示大小可变的项列表
ArrayList myArrayList = new ArrayList(); int i = 10;
myArrayList.Add(i); double d = Math.PI; myArrayList.Add(d);
Console.WriteLine(\foreach (Object obj in myArrayList) Console.WriteLine(obj.ToString()); 定义集合
? 创建自己的、强类型化的集合
? 一种方式是手动编写需要的方法,但这比较花时间,通常也非常复
杂;
? 另一种比较简单的方式是从一个集合类派生自己的集合,例如
System.Collections.CollectionBase类,这个抽象类提供了集合类的许多实现方式。
? CollectionBase类要求其派生类实现IEnumerable、ICollection和IList接口,
为了便于完成任务,CollectionBase类提供了两个受保护的属性:List和InnerList,它们可以访问存储的对象本身。List可以通过IList接口访问集合中的项,InnerList则是用于存储项的ArrayList对象。
集合类 class Prgram {
static void Main(string[] args) {
Persons ps = new Persons(); Person p1 = new Person(); ps.add(p1); ps[0].f();
Console.Read(); } }