您的位置:知识库 » .NET技术

我眼中的C# 3.0

作者: Allen Lee  来源: 博客园  发布时间: 2008-08-14 20:09  阅读: 3585 次  推荐: 1   原文链接   [收藏]  
摘要:每次有新技术发布时,我们总能感受到两种截然不同的情绪:一种是恐惧和抵抗,伴随着这种情绪的还有诸如“为什么要在C# 3.0搞到那么复杂”;另一种则是兴奋和拥抱,伴随着这种情绪的还有诸如"原来这个问题在C# 3.0里可以这么简单!"
[1] 你是如何创建属性的?
[2] 你是如何初始化对象的?
[3] 你是如何把运算逻辑外包出去的?
[4] 你是如何为对象扩展与之相关的功能的?
[5] 你是如何表达你想要的东西的?

你是如何表达你想要的东西的?

  现在,假设我想找到最便宜的LINQ的书,使用C# 2.0的语法,我可能需要这样:

代码 23

  虽然我已经使用了Array.IndexOf()方法、 List<T>.Sort()方法和匿名函数来简化代码,但仍然无法掩盖一个事实,那就是我在讲述如何获取我想要的东西,而这也正是命令式编 程(Imperative Programming)的核心思想。

  如果使用C# 3.0的语法,情况将会大不一样:

代码 24

  在这里,你表达了你想要的东西,而不是获取这些东西的具体 步骤,这是声明式编程(Declarative Programming)的核心思想,这样做的好处是明显的,你的需求可以被重新解析并执行,必要时还可以对底层的实现进行优化,但由于你并不关心和牵扯 到具体的实现上,所以那些优化并不会导致你修改代码。

  命令式编程就像过程管理,你深入执行的细节,继而对整个过 程的执行实施控制;而声明式编程则像目标管理(MBO),你制定目标,并把任务分配下去执行。代码23给人的感觉就是整个执行过程都非常的清楚,你可以对 任何一个步骤进行修改或者调优;而代码24给人的感觉就是你除了说出你想要什么,你什么也不能做,这对于那些过程管理拥戴者来说可能是不可接受的,他们感 到对事物失去了控制,无法建立安全感,因而产生了焦虑。曾经有人向我抱怨:如果你使用了LINQ,你就只能迫使自己相信它的实现是很好的。想想看,如果你 的公司把饭堂业务承包给一个餐饮公司,你的公司可以插手别人如何招聘厨师、如何采购食物、如何烧菜烧饭吗?选择LINQ意味着你愿意把执行细节交给别人去 处理,从而脱离这些细节,如果你根本无法放下对这些细节的控制,那么LINQ可能并不适合你。

  很难说这两种编程方式孰优孰劣,因为在某些场合下,善于过 程管理的管理者确实更能让事态朝正确的方向发展;而在另一些场合下,目标管理为实现者提供足够的自由度,更能激励他们积极地进行思考。管理界对于过程管理 和目标管理孰优孰劣之争论似乎从来没有停过,更何况编程界对于命令式编程和声明式编程孰优孰劣之争论,我个人倒是更倾向于把这看成是找出更适合你自己的风 格,而不是盲目听信别人的说法。语言到底是发挥积极作用还是消极作用在很大程度上是取决于使用者的,我们应该使用语言有利的一面来协助我们的工作,而不是 使用其有害的一面来伤害自己和别人。

  回到代码24,它把满足条件的书的所有信息都返回给我,如果我只需要书名和作者名字呢?我们知道,在面向对象的世界里,信息储存在对象里,于是我们不得不走到一个尴尬的境地,那就是我们要为此创建一个临时类:

代码 25

  噩梦正式开始了,如果我需要书名和价格呢?如果我需要书名、作者和价格呢?……(读者可以自行补全这个列表)这个时候就轮到C# 3.0的匿名类型和隐式类型化变量出场了:

代码 26

  因为匿名类型是由编译器自动生成的,而在你写代码的时候它 还没有名字,所以你无法用这个类型来声明这个变量,此时"var"关键字就派上用场了。这个是"var"关键字的最初目的,但得益于类型推断系统,我们还 可以使用"var"关键字声明任何本地变量,只要我们在声明的同时给予它初始化,否则编译器无法进行推断。曾经有人问我:如果我想返回代码26里的 wanted7怎么办?我们知道,方法的返回值需要明确给出类型,而在我们写下代码26时,编译器还没有给查询表达式里的匿名类型取名。如果你真的要把它 返回,你只能把方法的返回值类型定为IEnumerable<object>,因为我们只能确定匿名类型是object的后代,但这样一来, 客户端代码的日子就不太好过了,因为除了通过反射来访问你的对象,它别无他选。如果你真的要把它返回,那就意味着你和客户端代码有共享这个对象的需求,此 时恰当的做法应该是使用命名类型。另外,代码26里构建匿名类型时的"book.Title"是"Title = book.Title"的简写,当你省略"Title ="时,编译器会假定你希望匿名类型的这个属性的名字和Book.Title的一样。

  匿名类型还有一个有趣的地方,它曾经是可变的(mutable),后来却变成不可变的(immutable),Sree《Immutable is, the new Anonymous Type》一 文中给出了这个转变的解释。我们知道,在面向对象的世界里,对象封装并维护自身的状态,我们通过调用对象的方法所产生的副作用来影响对象的状态,而不可变 则是函数式编程(Functional Programming)的核心特征,或许你已经感受到了,C# 3.0引入了大量函数式编程的东西,而函数式编程语言似乎也要风生水起,这究竟意味着什么呢?

前路在何方?

  无论你是否承认,C# 3.0在表达上比它之前的版本要来的简单,但要获得这种简单,你必须先用很多东西武装自己的脑袋,这使我想起曾经在一本书里看到的一句话:

简单是由复杂来支撑的。

  不同语言之间的相互渗透已经不再是什么新奇之事了,引入其 它语言的功能有时候甚至可以看作是在战略上入侵对手的市场,这在某种程度上有点像金融业的混业经营。下一个版本的C#将会是怎样的呢?或许这个问题令你兴 奋不已,你甚至希望现在就让C# Team看看你的创造力;或许这个问题令你痛心不已,你害怕自己无法适应下一波的变革,因为变革可能导致动荡,动荡可能带来失控,失控可能引发焦虑。不管 怎样,该来的是无法回避的,或许现在先让我们看看Matthew Podwysocki的《What Is the Future of C# Anyways?》是否有一些启示……

1
0
标签:C#

.NET技术热门文章

    .NET技术最新文章

      最新新闻

        热门新闻