1.Net FrameWork:为开发应用程序而创建的一个平台(可以是运行在windows ,也可以是运行在其他操作系统)。例如Mono,它是.net framework的开源版本(包括C# 编译器),该版本可以运行在几个操作系统上,包括Linux 和 Mac Os。另外Mono还有一些版本可以运行在IPhone和Androis。 .Net Framework代码库中定义了一些基本类型,这种公共类型系统(Common Type System,CTS)有助于使用.net framework的各种语言之间进行交互操作;还包含公共语言运行库(Common Language Runtime, CLR),它负责管理.net 库开发的所有应用程序的执行。
2.使用.net 库编写应用程序,就是使用.net 代码库编写代码。为了执行C# 代码,我们必须把他们转换为目标操作系统能理解的语言,即本机代码(native code)。这种转换称为编译代码,由编译器执行。但在.net framework下,此过程包括两个阶段。CIL和JIT。
CIL:在编译使用.net 库代码的时候,不是立即创建勇于操作系统的本机代码,而是把代码编译为通用中间语言(CIL)代码,这些代码并非专门用于任何一种操作系统,也非专门用于C#。在开发C#应用程序时,这个编译步骤由VS完成。
JIT:显然要执行应用程序,必须完成更多工作,这是Just-In-Time(JIT)编译器的任务,它把CIL编译为专用于OS和目标机器结构的本机代码。这样OS才能执行应用程序。这里编译器的名称Just-In-Time反映了CIL代码仅在需要时才编译的事实。这种编译可以在应用程序的运行过程中动态发生,不过开发人员一般不需要关心这个过程。(提示:MSL或IL是CIL的旧称。)
程序集:编译应用程序时,所创建的CIL代码存储在一个程序集中。程序集包括可执行的应用程序文件(这些文件可以直接在windows 上运行,不需要其他程序,其扩展名是.exe)和其他应用程序使用的库(.dll)。除了CIL外,程序集还包括元信息(即程序集中包含的数据信息,也称为元数据)和可选的资源(CIL使用的其他数据,声音图片)。元信息允许程序集是完全自描述的,不需要其他信息就可以使用程序集,也就是说,我们不会遇到没有把需要的数据添加到系统注册表中这样的问题,而在使用其他平台进行开发时这个问题常常出现。
部署:因此部署就很简单了。只需把文件复制到远程计算机的目录下即可。因为不需要目标系统上的其他信息,所以只需从该目录中运行可执行文件即可(假定安装了.net CLR)。
托管代码:在将代码编译为CIL,再用JIT编译器将它编译为本机代码后,CLR的任务尚未全部完成,还需要管理正在执行的用.net 库编写的代码(这个执行代码的阶段通常称为运行时(runtime)),即CLR管理着应用程序。利用CLR的托管功能,让.net 处理与操作系统的任何交互。
托管代码和非托管代码:主要区别在于程序执行时内存管理的方式。托管代码由运行时统一管理,通过运行时与底层(硬件和操作系统)交互,非托管代码是直接在操作系统上运行的,意味着程序员要手动开辟和释放内存。
虚拟机中调用非托管代码:托管代码必须在托管平台(运行时)上运行,然而我们却可以在虚拟机中运行非托管代码。Mono使用P/Invoke技术实现在托管代码中调用非托管代码中的函数。P/Invoke技术是.net framework提供的一种机制,勇于在托管代码中调用非托管代码。使用P/Invoke技术需要使用DLLImport特性声明非托管函数的签名,并注意数据类型和调用约定的匹配。在调用非托管函数时,需要手动管理内存,以避免内存泄漏和其他内存相关的问题。
垃圾回收: 托管代码最重要的一个功能是垃圾回收。
链接:多个源文件编译到一个程序集中。
总结下流程就是:源文件C#代码先被编译为CIL中间代码,存储在程序集中,运行程序集(执行程序的时候),再由JIT编译器编译为本机代码,在托管的CLR(公共运行时)环境下运行本机代码。
3.面向对象
委托:是一种存储函数引用的类型。委托的声明类似于函数,但不带函数体,且要使用deltegate关键词。定义了委托后,就可以声明该委托类型的变量。接着把这个变量初始化为与委托具有相同返回类型和参数列表的函数引用。例如,可以把委托变量作为参数传递给一个函数,这样该函数就可以使用委托调用它引用的任何函数,而且在运行之前不必知道调用的是哪个函数。
接口是公共实例(非静态)方法和属性组合起来,以封装特定功能的一个集合。一旦定义了接口,就可以在类中实现它。
抽象类:不能直接直接实例化,必须继承。抽象类可以有抽象成员,这些成员在基类中没有实现代码,所以派生类必须实现他们。非抽象成员可以有自己的实现。
多态性:在面向对象编程范式中,多态性往往表现为“一个接口,多个功能”。多态就是同一个接口,使用不同的实例而执行不同操作。静态多态性表现为函数重载和运算符重载;动态多态性通过抽象类和虚方法实现。子类继承抽象父类,抽象成员方法在子类可以通过override重写,子类继承父类虚方法时,虚方法在子类也可以通过override重写。
接口的多态性:可以建立接口类型的变量,然后就可以在支持该接口的对象上,使用这个变量来访问该接口提供的方法和属性。
对象之间的关系:继承,包含,集合。
密封类:sealed 关键字,主要用来防止被继承
System.Object:C#中所有类默认继承自System.Object
构造函数,构造函数初始化器,base,this。在创建子类实例时,构造函数的执行序列是:先执行system.object(),再执行父类,最后执行子类自己的。base关键词指定在实例化过程中,使用基类中具有指定参数的构造函数。this关键字指的是调用指定的构造函数前,对当前类使用非默认的构造函数。
类库:VScode 新建类库 生成解决方案 .dll
抽象类和接口:抽象类主要用作对象系列的基类,这些对象共享某些主要特性,例如共同的目的和结构。接口则主要用于类,这些类存在根本性的区别,但仍可以完成某些相同的任务。
在这样的层次结构中,一些类共享相同的特性,这是因为他们的目的是相同的,而不只是因为他们派生于同一个基类。在进行更详细的分解之前,把对象系统以这种方式进行分解,可以清晰地看到哪种情形适合使用抽象类,哪种情形适合使用接口。只使用接口或只使用抽象继承,就得不到这个示例的结果。
部分类(partial)
4.示例:开发一个类模块(包含两个类);再开发一个简单的客户程序,确保这个模块能正常使用。
规划应用程序:开始编写代码前,应规划一下需要的结构和类的功能。
5.集合、比较和转换
集合:ICollection,IDictionary, IList.
定义集合:继承抽象类:CollectionBase
比较:对象之间的比较。类型比较,值比较。
类型比较:在比较对象时,常需要了解它们的类型,才能确定是否可以进行值得比较。GetType()方法,所有的类都从System.Object中继承了这个方法,这个方法和typeof()运算符一起使用,就可以确定对象的类型(并据此执行操作)。
装箱和拆箱:值类型-》引用类型=装箱;反之拆箱。
is运算符:用来检查对象是不是给定类型或是否可以转换为给定类型。
值比较:运算符重载,IComparable
类型转换: as运算符
6.泛型
可空类型 ?
??运算符:允许给可能等于null的表达式提供另一个值。如果第一个操作数不是null,就等于第一个操作数,否则,第二个。
?.空条件运算符
List 泛型集合类型,便捷,易用。不然还需要从CollectBase中派生一个类,然后实现需要的方法。
定义泛型类型:泛型类 泛型接口 泛型方法 泛型委托
泛型类:default 关键字
7.高级C# 技术
:: 运算符,结合gloabl一起使用,表示顶根名称空间的别名。这有助于更清晰地说明要指向哪个名称空间。
定制异常
事件
特性:
读取特性:反射
创建特性
初始化器:对象初始化器,集合初始化器
类型推理:var
匿名类型
动态类型
高级方法参数:
可选参数
Lamda表达式
8.文件
File 、Directory, 流类访问,文件读写,读写压缩数据,
序列化和反序列化对象,监控文件和目录变化
1.类库 框架 组件
2.设计模式
计算机擅长固定工作和记忆工作
固定工作:计算机如实且飞快地执行程序中的命令,只要条件相同,无论执行重复多少次,结果都一样,并不会对工作感到厌倦。
记忆工作:准确存储庞大的信息,并随时取出。
计算机在这两方面相比于人来说有绝对的优势,因此,利用计算机,人们能够变得轻松很多。