理论学习 C#

来源:互联网 发布:软件项目维护费用标准 编辑:程序博客网 时间:2024/06/05 01:08

C# 1.0,纯粹的面向对象
但由于它仅提供了二进制层面上的统一,因此无法将类型信息和用于支持基础平台和开发工具的信息放到组件中。这时,Java正在逐步走向成熟。于是,微软学习Java
  的做法,将虚拟机的概念引入到了COM领域;同时,微软提出了“元数据”的概念,用于描述组件的类型信息和工具支持信息,并决定将其放入到组件当中。这种“COM虚拟机”的名字在经历了若干争论后,最终被定为CLR(Common Language Runtime,公共语言运行时)。
软提出了在该运行时上运作的语言应该遵循的一些规则,以及该虚拟机的类型系统和指令集——所有这些规范形成了最终的C L I(Common Language Infrastructure,公共语言基础设施),并提交给了ECMA委员会。同时,微软开发了CLI的一个实现,这就是大名鼎鼎的.NET了。
这一时期的C#(以下称为C# 1.x)提出了纯粹的面向对象概念,并在语言特性中展现得淋漓尽致。C++并非纯面向对象的,为了和C兼容以及提供更高的执行效率,它保留了很多模块化的东西。Java尽管号称是面向对象的,但实际上,对于对象所应该具备的三种构成结构——属性、方法和事件,Java仅提供了方法,其它两种结构都要通过方法来模拟
通过委托(稍后介绍),结合关键字event,C#提供了优雅的事件概念。使用+=运算符,开发者可以非常方便地将一个事件处理器关联到一个事件上,这个过程称之为“订阅”一个事件。由于委托内部封装了一个调用链表,因此可以方便地为一个事件添加多个事件处理器,这些处理器会自动地依次调用。多年的开发语言进化证明,函数指针是非常重要也是非常危险的语言特征之一。同时,基于函数指针的回调机制也Windows 核心概念之一。然而,由于函数指针很难验证参数的类型准确性,因此C#(确切地说是CLI)提出了“委托”的概念,这是一种类型安全的函数指针链表。这意味着,C#不仅可以提供回调机制,同时调用回调的一方还无需在其内部维护函数指针列表,所要做的仅仅是声名一个具有恰当委托类型的公共成员即可;而提供回调的一方也只需通过构造一个带有指定方法的相应委托实例,并通过“+=”运算符添加到回调列表即可。

C# 2.0,泛型编程新概念
C# 2.0为开发者带来的最主要的特性就是泛型编程能力。和面向对象思想一样,泛型思想也是一种已经成熟的编程思想,但依然是没有哪一种主流开发语言能够支持完备的泛型概念。这主要是因为泛型的概念在一定程度上对面向对象概念进行冲击,同时,由于在编译期间对类型参数的完全检测很难做到,很多问题会被遗留到运行时。C# 2.0别出心裁,对泛  型类型参数提出了“约束”的新概念,并以优雅的语法体现在语言之中。有了约束,结合编译器强大的类型推断能力,可以在编译时发现几乎所有“危险”的泛型应用。
匿名方法除了可以使得事件处理器的编写更加精简以外,还将开发者带入了程序设计的一个新的领域——函数式编程,曾经有高人就用匿名方法结合泛型编程实现了函数式编程中的重要结构—— Lambda 表达式

C# 3.0,就不得不提一下微软的LINQ 项目,LINQ(语言集成查询,Language Integrated Query)提出了一种通过面向对象语法来实现对非面向对象数据源的查询技术,可查询的数据源从关系型数据库延伸到一般意义上的集合(如数组和列表)以及XML。而C# 3.0则是率先实现了LINQ的语言。在C# 3.0中,我们可以用类似于SQL语句的语法从一个数据源中轻松地得到满足一定条件的对象集合
Where并非names的成员方法,微软也没有对数组类型进行任何改动。这是C# 3.0中另外一个重要的新特性:扩展方法。扩展方法是定义在其他静态类中的静态方法,其第一个参数的类型就是希望扩展的类型,并且这个参数被冠以this修饰符。扩展方法是静态的,但可以像调用被扩展类型的实例方法那样进行调用,看起来好像是被扩展类型自己的方法一样。
我们又发现了一种奇怪的语法:n => n.Length > 5。这就是我们上文提到过的Lambda 表达式。微软的官方规范中称,Lambda 表达式是匿名方法的一种自然进化。因此Lambda 表达式其实也是一种特殊的委托,由编译器负责生成一个匿名的委托类型,它接受一个字符串类型的参数n;返回值为布尔类型,表示n的长度是否大于5;其中的参数类型和返回值类型都是由编译器推断而来的。说到类型推断,还要解释的一点就是上面的语句中出现的新关键字var。从出现的位置来看,var应该是一个类型。然而这又不是一个C#内建类型,也不是CLI提出的新类型;它只是一个“占位符”,它的确表示一个类型,但具体是什么类型需要编译器在编译期间进行推断。
Lamda表达式的真正意义不仅仅在于简化了委托的编写方式,更重要的是它把代码表达式体现为了数据。换句话说,Lambda表达式不仅可以被编译为一段可以执行的代码(类似于匿名方法),也可以将其翻译为一个数据结构——表达式树


 关键字 描 述
  abstract 可以和类、方法、属性、索引器及事件一起使用,
  标识一个可以扩展但不能被实体化的、必须被实现的类或方法。
  as 一个转换操作符,如果转换失败,就返回null。
  base 用于访问被派生类或构造中的同名成员隐藏的基类成员。
  catch 定义一个代码块,在特定类型异常抛出时,执行块内代码。
  参见try和finally。
  checked 既是操作符又是语句。
  确保编译器运行时,检查整数类型操作或转换时出现的溢出。
  const 标识一个可在编译时计算出来的变量值,即一经指派不可修改的值。
  delegate 指定一个声明为一种委托类型。委托把方法封装为可调用实体,
  能在委托实体中调用。
  enum 表示一个已命名常量群集的值类型。
  event 允许一个类或对象提供通知的成员,他必须是委托类型。
  explicit 一个定义用户自定义转换操作符的操作符,
  通常用来将内建类型转换为用户定义类型或反向操作。
  必须再转换时调用显示转换操作符。
  extern 标识一个将在外部(通常不是c#语言)实现的方法。
  finally 定义一个代码块,在程序控制离开try代码快后执行。参见try和catch。
  fixed 在一个代码块执行时,在固定内存位置为一个变量指派一个指针。
  foreach 用于遍历一个群集的元素。
  goto 一个跳转语句,将程序执行重定向到一个标签语句。
  implicit 一个操作符,定义一个用户定义的转换操作符。
  通常用来将预定义类型转换为用户定义类型或反向操作。
  隐式转换操作符必须在转换时使用。
  interface 将一个声明指定为接口类型,即实现类或构造必须遵循的合同。
  internal 一个访问修饰符。
  namespace 定义一个逻辑组的类型和命名空间。
  operator 用来声明或多载一个操作符。
  out 标识一个参数值会受影响的参数,但在传入方法时,
  该参数无需先初始化。
  params 声明一个参数数组。如果使用,必须修改指定的最后一个参数。
  允许可选参数。
  readonly 标识一个变量的值在初始化后不可修改。
  ref 标识一个参数值可能会受影响的参数。
  sealed 防止类型被派生,防止方法和property被覆载。
  sizeof 一个操作符,以byte为单位返回一个值类型的长度。
  stackalloc 返回在堆上分配的一个内存块的指针。
  struct struct是一种值类型,可以声明常量、字段、方法、property、
  索引器、操作符、构造器和内嵌类型。
  throw 抛出一个异常。
  try 异常处理代码块的组成部分之一。try代码块包括可能会
  抛出异常的代码。参阅catch和finally关键字。
  typeof 一个操作符,返回传入参数的类型。
  unchecked 禁止溢出检查。
  unsafe 标注包含指针操作的代码块、方法或类。
  using 当用于命名空间时,using关键字允许访问该命名空间中的类型,
  而无需指定其全名。也用于定义finalization操作的范围。
  virtual 一个方法修饰符,标识可被覆载的方法。
  volatile 标识一个可被操作系统、某些硬件设备或并发线程修改的attribute。

原创粉丝点击