讨论交流:http://x8.maicoo.com/team/8658.html
今天一来是有点空,二来是在博客上偶然看到有关于委托的文章,一时兴起,就自己也写一点心得与大家分享一下。
先看一个例子:
using System;
namespace ConsoleApplication1
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
bool m_isRight = false;
object m_obj = m_isRight?MyWrite("true"):MyWrite("false");
Console.Write(m_obj);
}
static private int MyWrite(object i_string)
{
Console.Write(i_string);
return i_string.ToString().Length;
}
}
}
问输出的结果是什么?有一个刚学习程序设计不久的学生的回答是:false false
这个结果给我的映像很深,为什么呢?因为我觉得这个不仅仅是学生的一个错误,而更多的是这个学生深入的思考了问题。
因为m_obj是一个对象,所以这个学生理解为:MyWrite()这个函数对象可以直接赋值给m_obj,然后m_obj就当成MyWrite()这个函数来调用,所以他就认为:
Console.Write (m_obj); 等于是:Console.Write (MyWrite(“false”));
这是思维是很有创意的,不是吗?
于是就是C#里而很多人不好理解的委托了。其实,从使用上讲,它就是一个函数变量!如上面的例子,如果真的是想把MyWrite()做为对象赋值给m_obj会是个什么结果呢?
我觉得我们先得解决以下几个问题,才能正确的把函数当成变量赋值给一个对象:
1、如果可以给一个对象赋函数值,如何来区别不同的函数?
2、如何区别它是一个函数赋值,还是一个普通的对象赋值?
3、如何用这个对象来调用原来的函数?
如果把这几个问题解决了,委托也就明白了一半。
先看问题1,如果可以给一个对象赋函数值,如何来区别不同的函数?
首先应该明白的是:C#里是可以对一个对象赋函数值的。解决这个问题的办法是先对该对象申明,申明它可以被什么样的函数来赋值,而这个对象申明在C#里的学名就是委托。
(在C++里称为函数指针申明,相应的对象也就叫做函数指针。Java里也不同的叫法,可惜我不知道。)
而它的语法就是:
delegate [function declare];
这里的function declare就包括了:
1、函数返回类型,
2、可用来存放函数的对象名(也就是委托名)
3、函数参数
所以完整的定义可以是:
delegate int MyDelegate(object I_object);
当然,合法的委托定义可以是:
delegate void MyDelegate();
delegate void MyDelegate(object I_1,object I_2);
…
现在,上面的语法就定义了一个抽象的对象MyDelegate, 注意,这里说的是抽象的对象,也就是说,你不能直接给MyDelegate赋函数,而只能在它的实例上函数,这是C#里特殊的要求。它的语法是:
MyDelegate m_delegate = new MyDelegate(与MyDelegate申明一致的函数名);
例如,以下是一个完全的,合法的委托申明与实例化一个对象:
delegate int MyDelegate(object i_object);
//
MyDelegate m_delegate = new MyDelegate(MyWrite);
//MyWrite函数如下,它是满足委托的申明的。
static private int MyWrite(object i_string)
{
Console.Write(i_string);
return i_string.ToString().Length;
}
现在我们就很好的解决了第一个问题,如何定义一个对象,使该对象可以把函数当变量来赋给它。而且,可以区别不同的函数类型,主要是通过函数返回值与函数参数来共区别一类函数。
OK,第二个问题:如果有了这样的一个对象后,如何来给它赋一个函数值呢?
其实上面的实例化一个委托对象时,就已经给它赋值了。上面的代码中,m_delegate就已经被赋值MyWrite,因此它已经具有了MyWrite函数的功能。
还有其实它的方法来给它赋值吗?有,在委托的一个应用中,可以看到其它的赋值方法。麦客学吧
【责任编辑: lanier】