突然写这篇文章真的有点是在做作的感觉我想这并不是什么难以理解的东西事实上很多人都写过而且我保证至少不比我写的差可是还是觉得有必要提出来因为要去正确的理解代理和事件是很有趣的也是很必要的那么好吧下面我就来讲讲它们之间的关系当然还会有些例子
首先我想说说有关事件事件顾名思义当然是windows程序收到的消息
那么我举几个有关事件的例子如鼠标移动按下之类的都是那么代理呢?很多人都说它看上去就是想是一个受托管的函数指针我觉得这种说法很正确事实如此在MSDN上我们经常可以看到有关代理的多路广播这个词我觉得不错可是不好理解但我会在下面详细讲解的
代理:(有的书上也翻译成指代或委托英文是这样一来的Delegate)
我想很多刚接触C#的人都会对代理产生兴趣的事实上也是如此不了解它你就没办法来做windows程序和传统意义上的函数指针有所不同的是代理在C#中是一种类型这样它看上去更安全也更符合OO精神代理实际上所做的工作就是通过引用把函数包裹起来并使函数有一个有效的返回值不知道我这样说是否好理解那么我举个例子你去建造房子很显然我是在说你所做的事情那么建造房子就是代理它指代了你要做的事情可是它并没有去做任何事情事实上是在建造房子这个工作里你做了那么结果是什么?当然是建立一座房子是的建造房子就是代理而如何建造房子则是函数应该完成的工作而建造的是什么样的房子则是返回值还记得我曾经说过代理是一种类型吗?呵呵我想你应该记得因为那是很新颖的至少当时我那么认为好吧让我们来看看名称空间SystemDelagate看见了吗?那就代理类
举个例子:
public delegate void GetString()//我申明了一个代理
现在我要用到它了如下;
int i=;
GetString gs=new GetString(iToString);//这里我吧int的ToString方法填入了一个代理中看上去想构造函数这就是常在书上看到的名称等效的而不是结构等效的我想看到这儿你还是不明白那么我再来一个代理
如下:
float j=;
GetString gs=new GetString(jToString);//瞧见了int的ToString方法和float的ToString方法的结构是不一样的可是名称和类型的返回值和参数都一样现在我想你应该理解了吧
可是我们经常会在MSDN中看到这样的句子单路代理和多路广播看上去有点不好理解
事实上我开始看这样的句子是有点头痛的那么我想例子是最好的解说方式
Single Delegate:(单路代理)
从字面上我们可以这样来理解这个代理只是单单代理了一个函数的工作那么好吧让我们来看看它是如何工作的下面我就来定义一个这样的代理:
public delegate bool Myfun(string strint i)
现在我再来写一个方法如下:
bool CompareStrToInt(string sint i)
{
if(sCompareTo(iToString())==)
return true;
else
return false;
}
这个方法完成的工作很简单对吧只是比较字符而已那么和代理有什么关系呢?还记得我说的话吗?代理就是在把动词名词化代码如下:
Myfun mf=new (CompareStrToInt);
string s=;
int i=;
ConSoleWriteLine(Value=+mf(si));
输出结果:
Value=true
这就是单路代理它只代理一个好吧也许你想看看复杂的例子更有趣的在后面呢该是讨论多路广播的时候了
多路广播:
一个代理同时代理几个方法就是我们前面说到的那样你去建造房子现在要不仅仅是建造住宅还的去建造花园等等其它建筑物可是它们都是在建造房子传递的参数也相同返回值的类型也相同都是房屋那么我们为什么不找一个代理人来完成这样的任务呢?把这些事物交由他一个人来完成不是可以节省我们很多的时间和金钱是的我们可以那样做SystemMulticastDelegate 实际上 framework中你还可以找到这个类多路代理MSDN上翻译成多路广播事实上它还重载了操作符+=其实多路广播和单路代理在使用方法上区别不大你可以看下面的例子
using System;
namespace Multi_castDelegate
{
/// <summary>
/// Summary description for Class
/// </summary>
class MyClassDelegate
{
/// <summary>
/// The main entry point for the application
/// </summary>
public delegate string IntDelegate(string s);
}
}
using System;
namespace Multi_castDelegate
{
/// <summary>
/// Summary description for MyImplementingClass
/// </summary>
public class MyClass
{
public MyClass()
{
}
public static string WriteString(string s)
{
ConsoleWriteLine(Writing string);
return null;
}
public static string logString(string s)
{
ConsoleWriteLine(loging string);
return null;
}
public static string TransmitString(string s)
{
ConsoleWriteLine(Transmitting string);
return null;
}
}
}
The Main class:
using System;
using SystemThreading;
namespace Multi_castDelegate
{
/// <summary>
/// Summary description for Test
/// </summary>
public class Test
{
public static void Main()
{
MyClassDelegateStringDelegate
WriterLoggerTransmitter;
MyClassDelegateStringDelegate
myDelegate;
Writer=new
MyClassDelegateStringDelegate(MyClassWriteString);
/// calling Writer
Writer(hello i am Writer just acting like Single cast);
Logger=new MyClassDelegateStringDelegate(MyClasslogString);
///calling Logger
Logger(hello i am Logger just acting like Singlecast);
Transmitter=new MyClassDelegateStringDelegate(MyClassTransmitString);
///calling Transmitter
Transmitter(hello i am Transmitter just acting like Singlecast);
///here mydelegate used the Combine method of SystemMulticastDelegate
///and the delegates combine
myDelegate=(MyClassDelegateStringDelegate)SystemDelegateCombine(WriterLogger);
myDelegate(used Combine);
///here Transmitter is also added using the overloaded form of Combine
myDelegate+=Transmitter;
myDelegate(Using Overloaded Form);
///now using the Remove method
myDelegate=(MyClassDelegateStringDelegate)SystemDelegateRemove(myDelegateWriter);
myDelegate(Without Writer);
///overloaded Remove
myDelegate=Transmitter;
myDelegate(Without Transmitter);
SystemThreadingThreadSleep();
}
}
}
(上面的例子是在一个国外网站上找到的觉得不错就直接套用了)
上面的例子重点是看那两个已经重载的操作符=和+=通过上面的例子你可以清楚的看到多路广播是如何一次代理多个方法的当然你也可以删除掉那些你不想要的用=操作符就可以了(那么我将在下一篇讨论事件)