看了这本《C# in Depth》的第一部分,觉得作者Jon Skeet对c#中的一些概念打的比方非常有意思,而且让人一下子就明白。
关于其中个人认为比较出彩的地方,记录如下:
1. delegate
通常大家提到delegate,往往就会提到C中的函数指针。诚然,两者确实有相似的地方,都是通过某种方式来间接调用方法。但是毕竟C#中的delegate不同于C中函数指针,而且单单提到函数指针也很难确切表达delegate的用处所在。还是来看看Jon是怎么来讲述delegate是个什么东东吧。
Jon说我们可以把这个delegate看做是一个人的遗嘱,里面列出了这个财产该怎么分配,是给情人还是老婆等等。但是这个遗嘱啥时候生效,执行情况如何,这个当事人(制定遗嘱的人)是不清楚也是控制不了的,因为遗嘱生效的时候他已经“挂”了。他只是希望在他见了上帝之后有人(他的律师)会按照他制定出来的计划执行。
这就说清楚了delegate的本质,它只是一个规范(参数类型,返回值类型)说明。至于delegate要做的事情,什么时候来做,这个delegate本身是不清楚的,它只是约定在执行任务的时候要符合它的约定。
那到底为啥我们需要delegate呢,在需要调用的方法的时候直接调用不就完事了,干嘛非要费事通过delegate来调用方法呢。这是因为有时候我们知道啥时候该调用某个方法,但是这个方法叫啥名字,这个方法会执行什么动作,调用者是不清楚的。 最明显的例子就是event。 例如,一个button它的click事件要处理什么动作,button本身是不清楚的,它只知道这个事件啥时候会触发。具体的执行动作通常由程序自己定义。
提到delegate,一般都会自然想到event。那delegate和event之间的区别是什么呢?
delegate和event之间最大的区别就是delegate相当于类的一个field,而event只是setter/getter方法(编译器会生成)。C#1 中声明一个event,首先都会声明一个delegate, 因为event是依赖于delegate的。 因此在声明event的类之外,只能来注册或取消事件处理函数,但是并不能改变event,不能调用event。这就做到了很好的封装。
2. Value type VS. Reference Type
关于value type和reference type区别的讨论非常司空见惯。但是Jon给出的比方却让我觉得眼前一亮。他说我们可以这样来理解value type和reference type的区别。
比如说你看到一本好书,比如《C# in Depth》你想推荐给你朋友看,你怎么办呢。你可以去复印室把你手头的这本书完整复印一边送给你朋友,这样你朋友手中的书的内容跟你手上的一模一样。而且,在这之后你在书上做注释,并不会影响到你朋友手上的书。
-- 这就说Value type。
那什么是reference type呢? 再比如,你在网上看到一个很好的网页(比如说wiki),然后你想分享给你的朋友。你通常会把该页面的URL赋值给你朋友(而不会把网页download下来,传给你朋友),这样你们看到的其实是同一个网页,你传给你朋友的只是页面的URL。如果你对该Wiki页面做了修改,你朋友也会看到修改的内容。那这个URL就可以看成reference.