对c#下函数,委托,事件的一点理解!_c#应用

2008-02-23 05:42:16来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

今天一来是有点空,二来是在博客上偶然看到有关于委托的文章,一时兴起,就自己也写一点心得和大家分享一下。

先看一个例子:

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函数的功能。

更有其实他的方法来给他赋值吗?有,在委托的一个应用中,能够看到其他的赋值方法。也就是另一个不好理解的概念:事件!后面会提到。

我们再来看一下最后一个问题:如何通过一个已赋值好了的委托对象,还调用他上面赋值了的函数。

这个最简单了,当一个委托实例赋了函数对象在上面后,就能够像调用原函数相同的来调用他了。因此,下面是个会法的调用:基于上面的申明。

m_delegate(“This is a delegate object to call the raw function.”);

他就等同于:

MyWrite(“This is a delegate object to call the raw function.”);

因此,上面的调用和原函数调用相同,会返回一个int结果。


OK,最后看一个完整的例子:

using System;
namespace ConsoleApplication1
{
class Class1
{
//先申明一个委托对象。
delegate int MyDelegate(object i_object);
[STAThread]
static void Main(string[] args)
{
MyDelegate m_delegate = new MyDelegate(MyWrite);
m_delegate("This is a delegate object to call the raw function.");
}
//该函数是满足上面委托对象的申明的。
static private int MyWrite(object i_string)
{
Console.Write(i_string);
return i_string.ToString().Length;
}
}
}


再来讨论一下他的应用:事件!

事件是其于委托的。我们还是先来看最开始的那个例子:

object m_obj = m_isRight?MyWrite("true"):MyWrite("false");

我想把一个函数对象赋值到m_obj上!但上面的委托只能在实例化对象的时候就直接给他赋值了。而现在是,在运行时对一个委托赋函数值。能够做到吗?

同样是有这样的向个问题,当然,前提是我们已知道有一种对象叫委托,他的实例能够赋函数对象。

下面的问题是:

1、假如能够在运行时给某个“特别委托”赋函数对象,如何实现?

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: c#2.0新的语法扩充(泛型,迭代器,匿名方法) _c#应用

下一篇: c#控制windows messenger和windows live messenger窗口发送消息