委托与事件 读书笔记

委托(delegate)

委托属于引用类型。
委托既可以引用静态方法也可以引用实例方法。
委托最大特点是,它不知道或不关心自己引用的对象的类。任何对象中的方法都可以通过委托动态地调用,而仅仅要求方法的参数类型和返回类型与委托的参数类型和返回类型相匹配而已。
使用委托:
 public delegate void MyFistDelegate(string message);//定义委托
class MyClass
{
public void WriteFistMessage(string message)
{
Console.WriteLine(message);
}
}
class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
MyFistDelegate myFist = new MyFistDelegate(myClass.WriteFistMessage);
myFist("委托本身调用了委托");
}
}
 
代码运行结果:

委托作为参数的使用:委托调用静态方法时,由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性,这样方法便可以将一个委托作为参数来接受 ,并且以后可以调用该委托,这称为异步回调。

public delegate void MyDelegate(int i,int j);
class MyNewClass
{
public static void Sum(int i,int j)
{
int sum = i + j;
Console.WriteLine("和:{0}+{1}={2}",i,j,sum);
}
public static void Prosuct(int i,int j)
{
int prosuct = i * j;
Console.WriteLine("积:{0}*{1}={2}",i,j,prosuct);
}
public static void MethodDelegate(int i, int j, MyDelegate myDelegate)//委托作为参数
{
myDelegate(i, j);
}
}
class Program
{
static void Main(string[] args)
{
MyNewClass.MethodDelegate(10, 10, MyNewClass.Sum);
MyNewClass.MethodDelegate(10, 10, MyNewClass.Prosuct);
}
}

代码运行结果:

多重委托:委托是一个特殊的对象,委托有一个用途在于可以使用“+”运算符将塔门分配给一个要成为多路广播的委托实例。组合委托可调用组成它的那两个委托,只有相同类型的委托才可以组合,就像字符串相加:
string s="Hello";
s+="World";
如果委托可以使用+运算符,那么也可以使用“-”运算符:
public delegate void MyDelegate(int i,int j);
class Program
{
static void Main(string[] args)
{
Program p = new Program();
MyDelegate del = new MyDelegate(p.Method);
del(10, 20);
Console.WriteLine("使用+运算符后,显示的结果");
del += p.Methodl;
del(20, 20);
Console.WriteLine("使用-运算符后,显示的结果");
del -= p.Method;
del(20, 20);

}
void Method(int i,int j)
{
Console.WriteLine("求和:{0}+{1}={2}",i,j,i+j);
}
void Methodl(int i, int j)
{
Console.WriteLine("求积:{0}*{1}={2}",i,j,i*j);
}
}
代码运行结果:

事件
发送事件的对象叫做事件发送方;捕获事件并对其作出响应的对象叫做事件接收方。
C#中,事件机制是借助于委托来实现的。
public class TemperatureEventArgs : EventArgs
{
private int temperature;

public int Temperature
{
get { return temperature; }
//set { temperature = value; }
}
public TemperatureEventArgs(int _temperature)
{
temperature = _temperature;
}
}
public class EventSender
{
public delegate void TemperatureEventHander(object sender,TemperatureEventArgs e);
public event TemperatureEventHander temperaturePress;
protected virtual void OnTemperaturePess(TemperatureEventArgs e)
{
TemperatureEventHander hander = temperaturePress;
if (hander!=null)
{
temperaturePress(this, e);
}
}
public void isTemperaturePess(int temperature)
{
OnTemperaturePess(new TemperatureEventArgs(temperature));
}
}
public class EventReceive
{
public void Press(object sender, TemperatureEventArgs e)
{
if (e.Temperature>80)
{
Console.WriteLine("报警器检测温度为{0},马上会发生火灾,请速撤离现场",e.Temperature);
}
else if (e.Temperature > 50 && e.Temperature <= 80)
{
Console.WriteLine("报警器检测温度太高,可能会发生火灾,请做好撤离现场的准备");
}
else
{
Console.WriteLine("这里温度正常,请安心工作");
}
}
}
class Program
{
static void Main(string[] args)
{

bool trueorfalse = true;
while (trueorfalse)
{
Console.WriteLine("请输入检测器温度,(只能输入数字,否则会出现异常):");
int temperature = Convert.ToInt32(Console.ReadLine());
EventSender es = new EventSender();
EventReceive er = new EventReceive();
es.temperaturePress += new EventSender.TemperatureEventHander(er.Press);
es.isTemperaturePess(temperature);
if (temperature>200)
{
trueorfalse = false;
}
Console.WriteLine("------------------------------------------------------");
Console.WriteLine("------------------------------------------------------");
}
Console.WriteLine("=================================================================");
Console.WriteLine("由于温度太高报警器已经损坏,程序将在5秒后退出程序");
Console.WriteLine("请等候......");
Console.WriteLine("距系统关闭还有5秒");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("离系统关闭还有4秒");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("离系统关闭还有3秒");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("离系统关闭还有2秒");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("离系统关闭还有1秒");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("...");

}
}
代码运行结果:

模拟邮局接收到新包裹向顾客发出通知这样一个简单过程。实际上是一个如何处理收到新包裹事件的问题。
事件发布者是邮局,顾客是事件的订阅者。为此,我们可以设计两个类:Post类和Customer类。
Post类作为事件发布者,其职责我们简单设计为:定义事件、将发生事件通知给订阅者。
Customer类作为事件订阅者,其职责设计为:订阅事件、处理事件。
为了将这两个类能够通过“收到新包裹” 事件关联起来,需要定义一个委托PackageHandler。
//邮局事件实例
/// 定义委托
public delegate void PackageHandler(string PackageOwner);
public class Post
{
/// 定义事件
public event PackageHandler SendMessage;
///定义事件触发方法
public void OnSendMessage(string msg) { SendMessage(msg); }
}
public class Customer
{
public string Name { get; set; }//自动实现属性
/// 订阅事件
public void Register(Post post)
{
post.SendMessage += new PackageHandler(HandleEvent);
post.OnSendMessage(Name);//触发事件
}
/// 定义事件处理方法
public void HandleEvent(string PackageOwner)
{
Console.WriteLine("{0}速到邮局领取包裹", Name);
}
}
class Program
{
static void Main(string[] args)
{
Customer cs = new Customer();
cs.Name = "张三";
cs.Register(new Post());
}
}

 
posted @ 2012-01-13 00:00  ·1234567890  阅读(548)  评论(0)    收藏  举报