C#高级编程第9版 阅读笔记(一)

一、前言

C# 简洁、类型安全的面向对象的语言。

.NET是一种在windows平台上编程的架构——一种API。

C#是一种从头开始设计的用于.NET的语言,他可以利用.NET Framework及其开发环境中的所有新增功能,面向对象的编程方法。

组件对象模型 COM Component Object Model

.NET的优点:面相对象编程,优秀的设计,语言无关,对动态Web页面的更好支持,高效的数据访问,代码共享,增强的安全性,对安装没有任何影响,web服务的支持。

.net framework 1.0 2002年发布

.net framework 2.0 对泛型的支持、新类和接口

.net framework 3.0 引入创建UI的新方式(WPF和XAML,基于矢量的图形替代了基于像素的图形)

.net framework 4.0 提供了动态语言集成和大量用于并行编程的新库

End Day 1 Page xix

第1章 .NET体系结构

1.1 C#与.NET的关系

1.2 公共语言运行库

公共语言运行库CLR 在CLR控制下运行的代码称为托管代码

编译的两个阶段:1、将源代码编译为Microsoft中间语言IL 2、CLR把IL编译为平台专用的代码。

1.3中间语言

IL总是即时编译的,称为JIT编译。

中间语言IL的主要特性:

a、面向对象和使用接口

用.NET建立的接口与COM接口共享一个理念:提供一个契约,实现给定接口的类必须提供该接口指定的方法和属性的实现。

语言互操作性的真正含义是用一种语言编写的类能直接用另一种语言编写的类通信。特别是:

²  用一种语言编写的类能继承另一种语言编写的类

²  一个类能包含另一个类的实例,而不管两个类是使用什么语言编写的。

²  一个对象能直接调用其他语言编写的另一个对象的方法

²  对象或对象的引用能在方法之间传播

²  在不同的语言之间调用方法时,能在调试器中交替调试这些方法调用,即调试不同语言编写的源代码。

b、值类型和引用类型的显著差异

值类型:变量直接存储其数据 一般存储在堆栈中

引用类型:变量仅存储地址,对应的数据在该地址中找到 存储在托管堆

c、强数据类型化

不允许对模糊的数据类型执行任何操作;

通用类型系统 CTS  Common Tpye System

公共语言规范 CLS  Common Language Specification

d、异常错误处理

e、特性的使用

1.4 程序集

程序集的两种类型:私有程序及 共享程序集

1.5 .NET Framework类

.NET Framework 4.5基类大致包含一下范围:

²    IL提供的核心功能

²    Windows UI支持和控件

²    在ASP.NET中使用Web窗体和MVC

²    使用ADO.NET和XML进行数据访问

²    文件系统和注册表访问

²    网络和Web浏览

²    .NET特性和反射

²    COM互操作性

1.6 命名空间

1.7 用C#创建.NET应用程序

创建Windows桌面应用程序的两种技术:windows窗体和WPF Windows Presentation Foundation。前者只是封装了原生windows空间,是基于像素图形的。

WPF是基于矢量图的。

WPF在创建应用程序时使用XAML。XAML 可扩展的应用程序标记语言eXtensible Application Markup Language

声明性编程:不利用编程语言而是通过编程来创建对象,是通过XML类型的编程来声明所有元素。

WCF是一种功能丰富的技术,提供了多重通信选项。记可以使用基于REST的通信,也可以使用基于SOAP的通信,都能获得标准Web服务提供的所有功能。

1.8 C#在.NET企业体系结构中的作用

第2章 核心C#

2.4 预定义数据类型

值类型存储在堆栈中,引用类型存储在托管堆上。

C#有15个预定义类型,其中13个是值类型,2个是引用类型string和object

预定义整数类型8个:sbyte short int long byte ushort uint ulong

预定义浮点类型2个:float double

预定义decimal 不财务计算专用,不是基本类型

预定义bool类型:

预定义字符类型:char

预定义引用类型2个:object string

2.5 流控制

条件语句:if  switch

循环语句:for while do…while foreach

跳转语句:goto break continue return

2.6 枚举

枚举是用户定义的整数类型,在声明一个枚举时,要指定该枚举的实例可以包含的一组可接受的值。

End Page 46

2.7 名称空间

2.8 Main()方法

2.9 有关编译C#文件的更多内容

2.10 控制台I/O

2.11 使用注释

2.12 C#预处理器指令

预处理器指令的命令不会转化为可执行代码中的命令,但会影响编译过程的各个方面。

2.13 C#编程规则

第3章 对象和类型

3.1 创建及使用类

3.2 类和结构

类和结构都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法。

类和结构的区别是他们在内存中的存储方式、访问方式。类是存储在堆heap上的引用类型。结构是存储在栈stack上的值类型。结构不支持继承。较小的数据类型使用结构可以提高性能。

3.3 类

End Page 79

3.4 匿名类型 是一个只继承自Object且没有名称的类

3.5 结构

结构总是派生自System.ValueType,System.ValueType派生自System.Object。

结构不支持继承;不允许有无参的构造函数;可以指定字段如何在内存中布局。

结构主要用于小的数据结构。但当把结构作为参数传递给方法时,应把它作为ref参数传递,以避免性能损失——此时只传递了结构在内存中的地址。

3.6 弱引用

弱引用允许创建和使用对象,但是垃圾回收器运行时,就会回收对象并释放内存。使用WeakReference类创建。

3.7 部分类

Partial关键字允许把类、结构、方法或接口放在多个文件中。

3.8 静态类

静态类在功能上与使用私有静态函数创建的类相同,不能创建静态类的实例。使用类型名即可进行静态类的调用。

3.9 Object类

所有的.NET类都派生自System.Object。

3.10 扩展方法

扩展方法是静态方法,它是类的一部分,但实际上没有放在类的源代码中。

第4章 继承

4.1 继承

4.2 继承的类型

实现继承:表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数。

接口继承:表示一个类型只继承了函数的签名,没有继承任何实现代码。

结构总是派生自System.ValueType,他们还可以派生自任意多个接口。

类总是派生自System.Object或用户选择的另一个类,它们还可以派生自任意多个接口。

4.3 实现继承

如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有分别声明为virtual和override,派生类方法就会隐藏基类方法。

C#中特殊的语法用于从派生类中调用方法的基类版本:base<MethodName>()

C#允许把类和函数声明为abstrac。抽象类不能实例化,抽象函数不能直接实现,必须在非抽象的派生类中重写。

C#允许把类和方法声明为sealed。对于类,表示不能继承该类;对于方法,表示不能重写该方法。

构造函数的调用顺序是先调用System.Ojdect,再按照层次结构由上向下进行,直到到达编译器要实例化的类为止。

4.4 修饰符

public protected intermal private

new static virtual abstract override sealed extern

4.5 接口

声明接口在语法上与声明抽象类完全相同,但不允许提供接口中任何成员的实现方法。一般情况下,接口只包含方法、属性、索引器和事件的声明。

不能实例化接口,它只包含其成员的签名。接口既不能有构造函数,也不能有字段。

在接口定义中不允许声明关于成员的修饰符。接口成员总是公有的,不能声明为虚拟或静态。

End Page 119

第5章 泛型

5.1 泛型概述

泛型可以创建独立于被包含类型的类和方法。

泛型类使用泛型类型,并可以根据需要用特定的类型替代泛型类型,保证了类型安全性。

泛型类、泛型接口、泛型方法、泛型委托。

值类型存储在栈上,引用类型存储在堆上。C#类是引用类型,结构是值类型。

引用类型共享同一个本地类的所有相同的实现代码,这是因为引用类型在实例化的泛型类中只需要4个字节的内存地址(32位系统),就可以引用一个引用类型。值类型包含在实例化的泛型类的内存中,同时因为每个值类型对内存的要求都不高,所以要为每个值类型实例化一个新类。

5.2 创建泛型类

5.3 泛型类

默认值:根据泛型类型是引用类型还是值类型,泛型default用于将泛型类型初始化为null或0。

约束:如果泛型类需要调用泛型类型中的方法,就必须添加约束。

继承:泛型类型可以实现泛型接口,也可以派生自一个类。

泛型类可以派生自泛型基类,其要求是必须重复接口的泛型类型或者必须指定基类的类型。

静态成员:泛型类的静态成员只能在类的一个实例*享。

5.4 泛型接口

.NET 4通过协变和抗变为泛型接口和泛型委托添加了一个重要的扩展。

协变和抗变指对参数和返回值的类型进行转换。

参数类型是协变的,方法的返回类型是抗变的。

如果泛型类型用out关键字标注,泛型接口就是协变的。

如果泛型类型用in关键字标注,泛型接口就是抗变的。

5.5 泛型结构

5.6 泛型方法

第6章 数组

6.1 同一类型和不同类型的多个对象

同一类型的多个对象可以使用集合和数组。不同类型的多个对象可以使用元组Tuple类型。

6.2 简单数组

数组是引用类型,所以声明了数组后,必须给它分配堆上的内存。

在指定了数组的大小后,如果不复制数组的所有元素,就不能重新设置数组的大小。如果事先不知道数组中应包含多少个元素,就可以使用集合。

6.3 多维数组

6.4 锯齿数组

End  Page 139

6.5 Array类

用方括号声明数组是C#中使用Array类的表示法。

在后台使用C#语法,会创建一个派生自抽象基类Array的新类。

Array类是一个抽象类,所以不能使用构造函数来创建数组。

如果数组的元素是值类型,复制数组就会复制所有值。

如果数组的元素是引用类型,则不复制元素,而只复制引用。

6.6 数组作为参数

数组支持协变,这表示数组可以声明为基类,其派生类型的元素可以赋予数组元素。

数组协变只能用于引用类型,不能用于值类型。

ArraySegment<T>表示数组的一段,此结构包含关于数组段的信息(偏移量和元素个数)。

数组段不复制原数组的元素,但是原数组可以通过ArraySegment<T>访问。如果数组段中的元素改变了,这些变化就会反映到原数组中。

6.7 枚举

在foreach语句中使用枚举,可以迭代集合中的元素,且无须知道集合中的元素个数。

数组或集合实现带GetEumerator()方法的IEumerable接口。GetEumerator()方法返回一个实现IEumerable接口的枚举,接着,foreach语句就可以使用IEumerable接口迭代集合了。

yield语句用于创建枚举器。yield return语句返回集合的一个元素,并移动到下一个元素上。yield break可停止迭代。包含yield语句的方法或属性也称为迭代块,迭代块必须声明为返回IEnumerator或IEnumerator接口,或者这些接口的泛型版本。这哥块可以包含多条yield return语句或yield break语句,但不能包含return。

6.8 元组

.NET Framework定义了8个泛型Tuple类和一个静态Tuple类,他们用作元组的工厂。

6.9 结构比较

第7章 运算符和类型强制转换

7.1 运算符和类型转换

7.2 运算符

7.3 类型的安全性

7.4 比较对象的相等性

End Page 169      Start 2017年10月8日

7.5 运算符重载    operator

C#要求所有的运算符重载都要声明为public和static。

C#要求必须成对重载比较运算符,且必须返回布尔类型的值。==和!= >和< >=和<= 三对。

7.6 用户定义的类型强制转换

隐式Implicit强制转换、显式Explicit强制转换

C#要求把类型强制转换的定义放在源类(或结构)或目标类(或结构)的内部。

End Page 189      Start 2017年10月9日

第8章 委托、lambda表达式和事件

8.1 引用方法

委托是类型安全的类,她定义了返回类型和参数的类型。

委托不仅包含对方法的引用,也可以包含对对歌方法的引用。

8.2 委托

在C#中,委托在语法上总是接受一个参数的构造函数,这个参数就是委托引用的方法。这个方法必须匹配最初定义委托时的签名。

为了减少输入量,只要需要委托实例,就可以只传送地址的名称,这称为委托推新。只要编译器可以把委托实例解析为特定的类型,这个C#特性就是有效的。

给定委托的实例可以引用任何类型的任何对象上的实例方法或静态方法——只要方法的签名匹配与委托的签名即可。

泛型Action<T>委托允许调用void返回类型的方法。

泛型Func<T>委托允许调用带返回类型的方法。

多播委托:按顺序连续调用多个方法,委托的签名必须返回void。

8.3 lambda表达式

8.4 事件

第9章 字符串和正则表达式

9.1 字符串

9.2 正则表达式:专门用于字符串处理的语言,一组用于标识字符类型的转义代码。

第10章 集合

10.2 集合接口和类型

10.3 列表 List<T>

10.4 队列 先进先出 Queue<T>

10.5 栈 后进先出 Stack<T>

10.6 链表 双向链表 LinkedList<T>

10.7 有序列表 基于键对所需集合排序 SortedList<TKey,TValue>类

10.8 字典 也称为映射或散列表 根据键快速查找值 Didtionary<TKey,TValue>

Lookup<TKey,TElement> SortedDictionary<TKey,TValue>

10.9 集 HastSet<T>不重复元素的无序列表 SortedSet<T>不重复元素的有序列表

10.10 可观察的集合 ObservableCollecton<T>

10.11 位数组

BitArry类引用类型,可以重新设置大小

BitVector32结构 值类型,是基于栈的,速度快。

10.12 不变的集合 Immutable.Collections

10.13 并发集合 Collections.Concurrent

10.14 性能

End Page 286

第11章 LINQ

11.1 LINQ概述 语言集成查询Language Integrated Query

查询表达式必须以from子句开头,以select或group子句结束,在这两个子句之间可以使用where、orderby、join、let和其他from子句。

在运行期间定义查询表达式时,查询不会运行,查询会在迭代数据项时运行。

11.2 标准的查询操作符

Where() 传递第二个参数索引,索引是筛选器返回的每个结果的计数器。

OfType() 基于类型的筛选

GroupBy()

11.3 并行LINQ

11.4 表达式树

11.5 LINQ提供程序

第12章 动态语言扩展

12.1 DLR Dynamic Language Runtime 动态语言运行时

12.2 dynamic类型 允许编写忽略编译期间的类型检查的代码

对于dynamic类型有两个限制。动态对象不支持扩展方法,匿名函数Lambda表达式也不能用做动态方法调用的参数,因此LINQ不能用于动态对象。大多数LINQ调用都说扩展方法,而Lambda表达式用作这些扩展方法的参数。

12.3 包含DLR ScriptRuntime

12.4 DynamicObject和ExpandoObject

End Page 332

第13章 异步编程

13.1 异步编程的重要性

C#5.0最重要的改进是提供了更强大的异步编程。新增两个关键字:async和await。

异步编程的方法调用是在后台运行(通常在线程或任务的帮助下)并且不会阻塞调用线程。

三种不同模式的异步编程:异步模式、基于事件的异步模式、基于任务的异步模式TAP。

新增的基于任务的异步模式TAP 是利用asynv和await关键字实现的。

13.2 异步模式

异步模式定义了BeginXXX方法和EndXXX方法。BeginXXX方法接受其同步方法的所有输入参数,EndXXX方法使用同步方法的所有输出参数,并按照同步方法的返回来型来返回结果。

使用异步模式时,BeginXXX方法定义了一个AsyncCallbak参数,用于接受在异步方法执行完成后调用的委托。BeginXXX方法返回IAsyncResult,用于验证调用是否已经完成,并且一直等到方法的执行结束。

基于事件的异步编程定义了一个带有Async后缀的方法。异步方法完成时,不是定义要调用的委托,而是定义一个事件。

基于任务的异步编程定义了一个带有Async后缀的方法,并返回一个Task类型。但是不需要生声明Task类型的变量来设置方法返回的结果。只要声明一个String类型的变量,并使用await关键字。await关键字会解除线程的阻塞,完成其他任务。

13.3 异步编程的基础

async和await关键字只是编译器功能。编译器会用Task类创建代码。

Async修饰符只能用与返回Task或void的方法,不能用于程序的入口点,即Main方法不能使用async修饰符。await只能用于返回Task方法。

组合器:一个组合器可以接受多个同一类型的参数,并返回同一类型的值,多个同一类型的参数被组合成一个参数来传递。Task组合器接受多个Task对象作为参数,并返回一个Task。

13.4 错误处理

13.5 取消

第14章 内存管理和指针

14.1 内存管理

14.2 后台内存管理

栈存储不是对象成员的值数据类型。栈是向下填充的,即从高内存地址向低内存地址填充。

栈指针表示栈中下一个空闲存储单元的地址。

14.3 释放非托管的资源

在定义一个类时,可以使用两种机制来自动释放非托管的资源。一种是声明一个析构函数或终结器,作为类的一个成员。另一种是在类中实现System.IDisposable接口。

14.4 不安全的代码

第15章 反射

15.1 在运行期间处理和检查代码

自定义特性允许把自定义元数据与程序元素关联起来,这些元数据是在编译过程中创建的,

并嵌入到程序集中。

反射是一个普通术语,它描述了在运行过程中检查和处理程序元素的功能。

15.2 自定义特性

特性类Attribute本身用一个特性——System.AttributeUsage特性来标记。

AttributeUsage更像一个元特性,因为它只能应用到其他特性上,不能应用到类上。

15.3 反射

System.Type:访问关于任何数据类型的信息。

System.Reflenction.Assembly:访问给定程序集的相关信息或者把程序集加载到程序中。

获取指向任何给定类型的Type引用有三种方法,具体如下:

Typeof(给定类型) Type t=给定类型.GetType()  Type t=Type.GetType(给定类型)

Type是许多反射功能的入口,实现许多方法和属性。

第16章 错误和异常

16.1 简介

16.2 异常类

16.3 捕获异常

16.4 用户定义的异常类

16.5 调用者信息

End Page 418

上一篇:expect 实现iterm2自动加载pem登录跳板机


下一篇:百万年薪python之路 -- MySQL数据库之 永久修改字符串编码 与 忘了密码和修改密码