Programmer & artist.

[c#基础系列一]:理解c#

  首先在介绍c#的时候我们要先理解什么是.NET,.NET就是微软的用来实验XML,Web Services,SOA(面向服务的体系结构service-oriented architecture)和敏捷性的技术。

Microsoft Windows Server System包括(图1)的内容

            (图1)

  .NET的初级组成是CIL和CLR,CIL是一套运作环境说明,包括一般系统、基础类库和与机器无关的中间代码,全称为通用中间语言(CIL)。CLR的核心功能包括:内存管理、程序集加载、安全性、异常处理和线程同步,可由面向CLR的所有语言使用。在CIL执行前,CLR必须将指令及时编译转换成原始机械码。

  而我们所说的C#是微软公司发布的一种面向对象的、运行于.NET Farmework之上的由CLR托管的高级程序设计语言。(p.s.按照.NET的说法,在CLR监视之下运行的程序属于“托管的”(managed)代码,而不在CLR之下、直接在裸机上运行的应用或者组件属于“非托管”(unmanaged)的代码。),值得注意的是c#并不能被编译成直接在计算机上执行的二进制代码,虽然和传统的可执行文件一样是.exe后缀,但是如果计算机上没有安装Farmework或者运行的计算机上Farmework版本低于编写程序时使用的版本这些程序将不能执行。

  明白了这些就知道了一点c#的工作原理,要学好c#还要知道一些历史以便在面对市场上各种c#版本方面的书的时候知道自己该选择什么。同时也能明白c#语言里面很多简洁的写法的源头,比如lamda表达式,linq语句等等,这样不会在学习的时候陷入只知其然不知其所以然的尴尬境地。

  c#是微软在2000年发布的一种新的编程语言,起初c#1.X只是一个单纯的面向对象的语言,尽管java宣称是面向对象的,可是面向对象的三个构成结构——方法,属性,事件,java只提供了方法其他两种要通过方法模拟,而c#1.0中所有面向对象的技术得到了很好的体现。另外在这个版本中c#就形成了类类型,值类型和接口类型的类型系统。同时c#1.0中还使用了加法赋值运算符 (+=) 来为事件附加事件处理程序这个过程称为订阅,我将会在以后几章里详细的讲解一下c#如何完成事件的订阅,而且在c#2.0里有更简单的语法去实现它。同时在c#1.0中就引用了委托机制(准确的说应该是CLI提出了委托机制[p.s.委托是一种类型安全的函数指针链表,后面我会用几个篇幅来介绍它])。

  在c#2.X版本中微软提出了范性编程的概念,同时微软发布了visualStudio2005,结合编译器强大的类型推断能力并提出了约束的新概念可以在编译时发现几乎所有的范性危险,而在c#2.X的版本中另外一个不得不说的概念就是匿名方法,用来取代仅出现一次的委托使程序员在写程序的时候能更注重于事件逻辑而不是语言本身,这将开发者带入了函数式编程的领域,匿名方法结合泛型编程这就是lamda语句的前身。在2.X版本中还增强了语言的表达能力比如访问器(get,set)可以有类型修饰符使只可读成为可能。同时还加入了迭代器的概念使程序可以不通过IEnumerator和IEnumerable接口就实现一个可以遍历的类型。

  值得一提的是在这里所说的迭代器并不是在CLI层面上实现的,而是通过编译器自动生成实现了IEnumerator和IEnumerable接口,这似乎体现了微软的某种倾向,果然在c#3.X版本中# 3.0加入了一堆新语法,尤其是在并没有修改CLR的情况下引入了Linq,在我看来这简直就是神来之笔,在linq中使用lamda表达式成了一种自然的选择,(p.s.实际上lamda表达式就是一个匿名的委托,后面的文章里我会向西介绍它)。值得一提的是c#3.X编译生成的IL代码是完全基于.NET2.0的,也就是说这一时期的c#已经离CLI越来越远,更多的工作交给了编译器(比如查询表达式和lamda表达式都不是基于CLI),这个时代的c#已经不再是一个简单的编程语言了,语言继承查询的引入使得那个时候讨论的热门的ORM技术得到了更深入的体现。

  在c#4.0中增加了动态语言的特性,从里面可以看到很多javascript、python这些动态语言的影子。为了实现动态,开发者需要加入dynamic关键字申明一个变量的static类型为dynamic(有点绕口)。这也是c#的一中进化,在3.0及之前,如果你不知道一个变量的类型,而要去调用它的一个方法,一般会用到反射:

1 object calc = GetCalculator(); 
2 Type calcType = calc.GetType(); 
3 object res = calcType.InvokeMember("Add", 
4 BindingFlags.InvokeMethod, null, 
5 new object[] { 10, 20 }); 
6 int sum = Convert.ToInt32(res); 

  有了dynamic,就可以把上面代码简化为:

1 dynamic calc = GetCalculator(); 
2 int sum = calc.Add(10, 20); 

  使用dynamic的好处在于,可以不去关心对象是来源于COM, IronPython, HTML DOM或者反射,只要知道有什么方法可以调用就可以了,剩下的工作可以留给runtime。(这里看不懂没关系,以后我会慢慢讲解这只是以前版本的c#实现的一种简洁进化),动态查找以及命名参数和可选参数这些新特征都有助于使针对COM的编程不再像以前那样的痛苦。这些妙不可言的好处不能在短短几行就分析出来,我会在后期的博文里给大家展现c#4.0编程的优雅,前提是需要对以前版本的c#有一个很好的理解,要不然当你面对那些简单的代码的时候将会有一种无所适从的感觉。

  下一节将会带大家从底层了解一下c#的编码和执行过程。

posted @ 2013-02-24 20:20  未命铭  阅读(596)  评论(2编辑  收藏  举报

Copyright ©2015 未命铭