Program.cs代码如下using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace Ch13.Ex02
{
class Program
{
static void Main(string[] args)
{
Connection myConnection = new Connection();
Display myDisplay = new Display();
myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage);
myConnection.Connect();
Console.ReadKey();
}
}
}Connection.cs代码如下using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;namespace Ch13.Ex02
{
public delegate void MessageHandler(string messageText); public class Connection
{
public event MessageHandler MessageArrived; private Timer pollTimer; public Connection()
{
pollTimer = new Timer(100);
pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
} public void Connect()
{
pollTimer.Start();
} public void Disconnect()
{
pollTimer.Stop();
} private static Random random = new Random(); private void CheckForMessage(object source, ElapsedEventArgs e)
{
Console.WriteLine("Checking for new messages.");
if ((random.Next(9) == 0) && (MessageArrived != null))
{
MessageArrived("Hello Mum!");
}
}
}
}Display.cs代码如下:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace Ch13.Ex02
{
public class Display
{
public void DisplayMessage(string message)
{
Console.WriteLine("Message arrived: {0}", message);
}
}
}问题如下:1.
初始化类的实例是不是就这种写法?
Connection myConnection = new Connection();
我看到很多程序都是先一个类名,再实例名=new 类名+一对小括号
2.
myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage);
这句在P301看到有相关解释,在这里应该理解为:使用事件处理方法初始化的一个新委托实例,这个命令(使用略微古怪的语法,专用于委托)在列表中添加一个处理程序,当引发MessageArrived事件时,就会调用该处理程序。
2.1 新委托实例的实例名是啥?MessageHandler么?这个不是在Connection.cs里就定义了一个公共委托了么?
2.2 “在列表中添加一个处理程序”,列表在哪儿?
2.3 什么时候引发了MessageArrived事件了?怎么引发的?3.
为何要myConnection.Connect();来启动定时器?Connect函数里才一句话,如果直接让pollTimer变成public的,那就可以直接myConnection.pollTimer.Start()了吧?或者直接把定时器放Program.cs里,就可以不用调用myConnection实例里的timer了4.
第八章讲到构造函数的定义是:用于初始化数据的函数。是不是可以简单的理解为C语言中的所有变量声明,结构体共用体之类的定义都要放在类的构造函数中?在本例的Connection()这个构造函数中,
pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
4.1 这句话是不是只能放在构造函数里?
4.2
private static Random random = new Random();
public event MessageHandler MessageArrived;
private Timer pollTimer;
为何不放在构造函数里呢?这不是初始化一个random变量么?不是初始化生成实例么?
4.3 这类事件委托程序的写法里,new后面的ElapsedEventHandler是不是固定的?在P301的写到:“Timer对象有一个Elapsed事件,这个事件要求的事件处理程序必须匹配System.Timers.ElapsedHandler委托类型的返回类型和参数,是.NET Framework中定义的标准委托。”也就是说一种事件对应一种委托,所以代码写到=+时,按下tab就是默认的常用委托了?
4.4 这个委托的两个函数,Timer对象本身,ElapsedEventArgs对象的一个实例,都没在CheckForMessage函数里用到啊?是不是这类的委托函数的参数可以不用非得在函数体里调用?5.
关于MessageArrived("Hello Mum!");的
5.1 P304解释说这是用MessageHandler委托类型声明了一个MessageArrived事件,委托不是应该声明一个委托么?怎么委托声明了事件了?
5.2 这句话为啥可以直接给一个字符串参数就能输出了?MessageHandler类型的委托函数名也没有出现在MessageArrived后的括号里啊?他们是怎么和Display类里的输出函数相关联的?
谢谢各位的宝贵时间了!
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace Ch13.Ex02
{
class Program
{
static void Main(string[] args)
{
Connection myConnection = new Connection();
Display myDisplay = new Display();
myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage);
myConnection.Connect();
Console.ReadKey();
}
}
}Connection.cs代码如下using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;namespace Ch13.Ex02
{
public delegate void MessageHandler(string messageText); public class Connection
{
public event MessageHandler MessageArrived; private Timer pollTimer; public Connection()
{
pollTimer = new Timer(100);
pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
} public void Connect()
{
pollTimer.Start();
} public void Disconnect()
{
pollTimer.Stop();
} private static Random random = new Random(); private void CheckForMessage(object source, ElapsedEventArgs e)
{
Console.WriteLine("Checking for new messages.");
if ((random.Next(9) == 0) && (MessageArrived != null))
{
MessageArrived("Hello Mum!");
}
}
}
}Display.cs代码如下:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace Ch13.Ex02
{
public class Display
{
public void DisplayMessage(string message)
{
Console.WriteLine("Message arrived: {0}", message);
}
}
}问题如下:1.
初始化类的实例是不是就这种写法?
Connection myConnection = new Connection();
我看到很多程序都是先一个类名,再实例名=new 类名+一对小括号
2.
myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage);
这句在P301看到有相关解释,在这里应该理解为:使用事件处理方法初始化的一个新委托实例,这个命令(使用略微古怪的语法,专用于委托)在列表中添加一个处理程序,当引发MessageArrived事件时,就会调用该处理程序。
2.1 新委托实例的实例名是啥?MessageHandler么?这个不是在Connection.cs里就定义了一个公共委托了么?
2.2 “在列表中添加一个处理程序”,列表在哪儿?
2.3 什么时候引发了MessageArrived事件了?怎么引发的?3.
为何要myConnection.Connect();来启动定时器?Connect函数里才一句话,如果直接让pollTimer变成public的,那就可以直接myConnection.pollTimer.Start()了吧?或者直接把定时器放Program.cs里,就可以不用调用myConnection实例里的timer了4.
第八章讲到构造函数的定义是:用于初始化数据的函数。是不是可以简单的理解为C语言中的所有变量声明,结构体共用体之类的定义都要放在类的构造函数中?在本例的Connection()这个构造函数中,
pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
4.1 这句话是不是只能放在构造函数里?
4.2
private static Random random = new Random();
public event MessageHandler MessageArrived;
private Timer pollTimer;
为何不放在构造函数里呢?这不是初始化一个random变量么?不是初始化生成实例么?
4.3 这类事件委托程序的写法里,new后面的ElapsedEventHandler是不是固定的?在P301的写到:“Timer对象有一个Elapsed事件,这个事件要求的事件处理程序必须匹配System.Timers.ElapsedHandler委托类型的返回类型和参数,是.NET Framework中定义的标准委托。”也就是说一种事件对应一种委托,所以代码写到=+时,按下tab就是默认的常用委托了?
4.4 这个委托的两个函数,Timer对象本身,ElapsedEventArgs对象的一个实例,都没在CheckForMessage函数里用到啊?是不是这类的委托函数的参数可以不用非得在函数体里调用?5.
关于MessageArrived("Hello Mum!");的
5.1 P304解释说这是用MessageHandler委托类型声明了一个MessageArrived事件,委托不是应该声明一个委托么?怎么委托声明了事件了?
5.2 这句话为啥可以直接给一个字符串参数就能输出了?MessageHandler类型的委托函数名也没有出现在MessageArrived后的括号里啊?他们是怎么和Display类里的输出函数相关联的?
谢谢各位的宝贵时间了!
classname objname = new classname(构造函数的参数)
2.1 新委托实例的实例名是啥?MessageHandler么?这个不是在Connection.cs里就定义了一个公共委托了么?myDisplay.DisplayMessage
2.2 “在列表中添加一个处理程序”,列表在哪儿?这里指委托链
2.3 什么时候引发了MessageArrived事件了?怎么引发的?这个要看类内部代码。
3 作为简单程序,主要为了说明方法。
为何不放在构造函数里呢?这不是初始化一个random变量么?不是初始化生成实例么?构造函数和初始化变量没有必然关系。
也就是说一种事件对应一种委托,所以代码写到=+时,按下tab就是默认的常用委托了?
事件和委托是多对1的关系。tab是IDE的功能而已。
是不是这类的委托函数的参数可以不用非得在函数体里调用?是的。
如同你写一个方法,未必一定要用到传入的参数。
5 这个你看msdn里面C#编程指南关于委托的概念。仔细理解下。
2.1 新委托实例的实例名是啥?MessageHandler么?这个不是在Connection.cs里就定义了一个公共委托了么?
MessageHandler是一种委托,这个委托在你的代码中有定义:
public delegate void MessageHandler(string messageText);然后Connection类中,用这个委托定义了一个事件:
public event MessageHandler MessageArrived;所以在代码中可以这样:
myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage);将myConnection对象的MessageArrived事件处理程序指定为一个MessageHandler类型的处理程序: public void DisplayMessage(string message)
{
Console.WriteLine("Message arrived: {0}", message);
}
这个程序的签名符合MessageHandler委托的定义2.2 “在列表中添加一个处理程序”,列表在哪儿?
MessageArrived事件的处理程序可以有多个,依照给他+=的顺序依次被调用,所以这是一个委托列表
2.3 什么时候引发了MessageArrived事件了?怎么引发的? private void CheckForMessage(object source, ElapsedEventArgs e)
{
Console.WriteLine("Checking for new messages.");
if ((random.Next(9) == 0) && (MessageArrived != null))
{
MessageArrived("Hello Mum!");
}
}
这里通过MessageArrived触发事件的。3.为何要myConnection.Connect();来启动定时器?Connect函数里才一句话,如果直接让pollTimer变成 public的,那就可以直接myConnection.pollTimer.Start()了吧?或者直接把定时器放Program.cs里,就可以不用调用myConnection实例里的timer了
你的Connection对象是通过使用定时器来触发事件的,所以必须要启动定时器,否则都不会导致MessageArrived事件被触发,如果直接那样是可以的,但是类的设计要保证该公开的才公开,不能全部都是Public
4.第八章讲到构造函数的定义是:用于初始化数据的函数。是不是可以简单的理解为C语言中的所有变量声明,结构体共用体之类的定义都要放在类的构造函数中?在本例的Connection()这个构造函数中,
pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
构造函数,是确保这个对象被New以后,内部的数据得到正确的初始化,以便能够供调用方正确使用,所以并不是你所理解的那样。
4.1 这句话是不是只能放在构造函数里?
另外:
pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
也不一定要防止构造函数里面,放在其他地方也可以,根据需要而已。
4.2private static Random random = new Random();
public event MessageHandler MessageArrived;
private Timer pollTimer;
为何不放在构造函数里呢?这不是初始化一个 random变量么?不是初始化生成实例么?
首先不能在实例方法中定义静态变量,所以这个不可以。
所以的构造函数只是确保对象能被外界使用之前,正确初始化一些状态信息,并不是所有的定义和初始化都要放在构造函数中。4.3 这类事件委托程序的写法里,new后面的ElapsedEventHandler是不是固定的?在P301的写到:“Timer对象有一个Elapsed 事件,这个事件要求的事件处理程序必须匹配System.Timers.ElapsedHandler委托类型的返回类型和参数,是.NET Framework中定义的标准委托。”也就是说一种事件对应一种委托,所以代码写到=+时,按下tab就是默认的常用委托了?
不是固定的,正如这句话所说:
“Timer对象有一个Elapsed 事件,这个事件要求的事件处理程序必须匹配System.Timers.ElapsedHandler委托类型的返回类型和参数,是.NET Framework中定义的标准委托。”
必须是符合事件的委托,才可以这样。
4.4 这个委托的两个函数,Timer对象本身,ElapsedEventArgs对象的一个实例,都没在CheckForMessage函数里用到啊?是不是这类的委托函数的参数可以不用非得在函数体里调用?
pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);Timer对象是为了定时调用CheckForMessage,它本身和ElapsedEventArgs对象,并不需要在CheckForMessage使用,这是肯定的,你要理解这里Timer对象是为了定时触发调用CheckForMessage
5.
关于MessageArrived("Hello Mum!");的
5.1 P304解释说这是用MessageHandler委托类型声明了一个MessageArrived事件,委托不是应该声明一个委托么?怎么委托声明了事件了?
委托可以理解成函数的签名,所谓函数的签名就是说这个函数返回什么类型的值,有什么类型的参数,有几个参数,事件是.NET提供的一种函数回调的封装,就是在某种情况发生时(这就是发生了某个事件),自动去调用一个方法,所以为一个事件添加处理程序是这样的:myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage);这里的MessageArrived 是事件,MessageHandler是一个委托类型,myDisplay.DisplayMessage是符合委托类型的一个函数,用于处理事件。
5.2 这句话为啥可以直接给一个字符串参数就能输出了?MessageHandler类型的委托函数名也没有出现在MessageArrived后的括号里啊?他们是怎么和Display类里的输出函数相关联的?
这里的 MessageArrived("Hello Mum!");等于是触发了一个事件,这回导致DisplayMessage函数被执行,“Hello Mum!”被传送到该函数进行输出。