1.C#基础之简介(完成)
刚才复习着就写了几个自己分不清的些概念,现在来写这个,最基本的创建一个"hello word"就不写了。
一.程序结构
C#中程序结构的关键概念为:程序、命名空间、类型、成员和程序集。C#程序一个或多个源文件,程序中声明类型,类型包含成员并能够被组织到命名空间中,类和接口是类型的例子,字段、方法、属性和事件则是成员的例子。
当C#程序被编译时,他们被物理地打包到程序集中,程序集的文件扩展名一般为.exe或者.dll,这个取决于它们是实现为应用程序,还是类库。程序集包括中间语言(IL)指令形式的可执行代码,以及元数据形式的符号信息;在它执行钱,程序集的IL代码将被.NET公共语言运行库(CLR)自动转换成特定处理器的代码。由于程序集是自描述的功能单元,它既包括代码,也包括元数据,所以C#中不需要#include指令和头文件,在程序需要引用特定程序集中的公共类型和成员,只需要在编译时引用那个程序集就可以,比如Console类,在引用命名空间有using System。
二.类型和变量
C#的类型有两种:值类型和引用类型
值类型变量直接包括它们的数据,而引用类型变量存储的时它们的数据引用;后者被认为是对象,对于引用类型,有可能两个变量引用相同的对象,对其中一个变量操作,可能影响到另一个对象引用的对象;而值类型,每个变量都有自己的数据拷贝,互不影响(ref和out参数变量例外)。借用书上的图片:
C#程序使用类型声明创建新类型,类型声明指定新类型的名字和成员。C#可由用户自定义的方法有五种:类类型、结构类型、接口类型、枚举类型和委托类型:
类类型:定义一个数据结构,包括数据成员(字段)和函数成员(方法、属性及其他),支持继承和多态;
结构类型:与类类型相似,带有数据成员和函数成员;但结构类型是值类型,不需要堆分配,且不支持用户指定的继承,所有的结构类型隐式地继承类型object;
接口类型:定义了一个约定,作为一组函数成员命名的集合,实现接口的类或结构必须提供接口函数成员的实现,接口可从多个基接口继承而来,类或者结构也可能实现多个接口;
枚举类型:是带有命名常量的独特类型,每个枚举类型有一个底层的类型,它必须是8个整型类型之一;
委托类型:通过特定的参数列表和返回类型表示对方法的引用;委托将方法处理为实体,实体能赋值给变量,也可以当作参数传递。
C#的类型系统是统一的,这样任何类型的值都能被处理成对象;C#中每一个类型都直接或间接从object类继承而来,因此object是所有类型最终的基类;所以引出装箱(值类型转化成引用类型)和拆箱(引用类型转化成值类型)的概念。
三.表达式
表达式:由操作数和运算符构成,关键是运算符的优先级。
四.类和对象
类:是C#类型中最基础的类型,是一个数据结构,将字段、方法和其他函数组合在一个单元;所以类的成员由静态成员,也有实例成员,静态成员属于类,实力成员属于对象(类的实例)。
类的每个成员都有关联的可访问性,它控制能访问该成员的程序文本区域,总共由5中可访问性:
类中还有一个重要知识就是继承,继承意味着类将隐式地包含其基类的所有成员(除了基类的构造函数)。派生类能在继承基类的基础上添加新的成员。
字段:与对象或类相关联的变量,声明时含有static修饰符时,该字段为静态字段,不管创建多少个类实例,静态字段只有一个副本;反之为实例字段,每个实例都包含该类所有实例字段的一个单独副本。
方法:一种用于实现可以由对象或类执行的计算或操作的成员;静态方法只能通过类来访问,实例方法则要通过类的实例访问;方法有返回类型,用于指定由该方法计算和返回的值的类型,如果方法不返回一个值,则它的返回类型为void;方法还有一个参数列表,表示传递给方法的值或引用。
参数:当方法被调用时,方法的参数从指定的自变量得到它们实际的值;C#有4种参数:值参数、引用参数、输出参数和参数数组。
值参数:用于输入参数的传递,相当于一个局部变量,初始值时从为该参数所传递的自变量获得的,对值参数修改不会影响所传递的自变量;
引用参数:用于输入和输出参数的传递,用于引用参数的自变量必须是个变量,它们所表示的是同一个存储位置,例如ref;
输出参数:用于输出参数的传递,类似引用参数,不同的是调用方提供的自变量初始值无关紧要,只在乎计算结果,例如out;
参数数组:允许将可变长度的自变量列表传递给方法,用params修饰符声明,只有方法的最后一个参数能被声明为参数数组,且必须是一维数组。
方法体:指方法调用时所要执行的语句,方法体能够声明特定于该方法调用的变量,这样的变量被称为局部变量(即在方法体内声明的变量);
若一个方法声明中含有static修饰符,则该方法为静态方法,静态方法只能访问静态成员;若没有static修饰符,则该方法称为实例方法,实例方法既能访问实例成员,也能访问静态成员。
若一个实例方法的声明中含有virtual修饰符,则称该方法为虚拟方法,虚拟方法可以由派生类重写override,虚拟方法声明用于引入新方法,而重写方法声明则用于使现有的继承虚拟方法专用化。说到虚拟方法,就必须提一下抽象abstract(我可不会说是我以前有点混淆),抽象方法其实就是没有实现的虚拟方法,而且抽象方法只允许在抽象类中使用,在继承的非抽象类的派生类必须重写抽象方法,修饰符也是使用override。
上面说的是重写,接下来说方法重载(我刚学也是分不清,概念绕的头晕):允许在同一个类中采用同一个名称声明多个方法,条件是它们的方法名是唯一的,即方法名相同,但参数不同,与有无返回值无关。
接下来说说C#支持的其他函数成员:
构造函数:C#即支持实例构造函数,也支持静态构造函数;实例构造函数是实现初始化类实例所需操作的成员,而静态构造函数是在类首次加载时用于实现初始化类本身所需操作的成员;还有实例构造函数时不能被继承。
属性:是字段的自然扩展,两者都是具有关联类型的命名成员,而且访问的语法也是相同的,但属性和字段不同,不表示存储位置;相反,属性有访问器,这些访问器是指定在它们的值被读取或写入时需执行的语句;属性的声明以定界符{}之间的get/set访问器结束,同时包含get和set访问器的属性被称为读写属性,只有get的是只读属性,只有set的是只写属性。这里就多说以下get和set访问器吧,get访问器相当于一个具有属性类型返回值的无参方法,除了作为赋值的目标外,当表达式中引用属性时会调用它;set访问器相当于一个具有单个名为value的参数和无返回类型的方法,当一个属性作为赋值的目标或运算符的操作数被引用时会调用它,所传递的自变量将提供新值。
索引器:使对象能用和数组相同的方式进行索引。声明方式和属性类似,不同的是索引器名是this,参数列表在[]中,比如public int this[int index];
事件:是使对象或类能够提供通知的成员,事件声明的关键字是event,且事件声明的类型必须是委托类型;意思是如果要在类的内部声明事件,首先必须声明该事件的委托类型;事件必须要在方法里去触发。下面代码定义了一个名为BoilerLogHandler的委托和一个名为BoilerEventLog的事件,该事件在生成的时候会调用委托。
public delegate void BoilerLogHandler(string status);
public event BoilerLogHandler BoilerEventLog;
运算符:用来定义可应用于类实例的特定表达式运算符的含义,即重新定义原有的运算符。有三种运算符能被定义:一元、二元和转换运算符,关键所有的运算符必须声明为public和static。
析构函数:是用于实现析构类实例所需操作的成员。析构函数不能带参数、可访问性修饰符,也不能被显式调用,垃圾回收期间会自动调用。
五.结构
结构:结构的声明关键字是struct,像类一样,结构也是表示可以包含数据成员和函数成员的数据结构。不同的是结构是值类型,结构类型不支持用户指定的继承。结构的用处:能自己定义所需要的新类,对于具有值语义的小的数据结构特别有用,因为对于小的数据结构,使用结构能节省大量的分配内存,比如复数、坐标系中的点或字典中的"键--值"对都是结构的典型实例。
struct 结构体名 {
public 类型 子变量名;
public 类型 子变量名;
...}
六.数组
数组:一种含若干变量的数据结构,这些变量通过索引进行访问,它们具有相同的类型。数组的实例通过new运算符动态创建,创建时指定数组实例的长度,new运算符自动将数组的元素初始化为它们的默认值,比如数值类型的将被初始化为零,引用类型的则被初始化为null。
int[] 数组名=new int[5];表示创建一个int的数组,数组元素有5个
上面说的是一维数组,C#也支持多维数组,数组类型的维数也被认为是数组类型的秩。声明时在[]中加逗号,n维数就加n-1个逗号
int[,] 数组名=new int[3,3] 二维数组 int[,,] 数组名=new int[3,3,3] 三维数组
上面说的数组都是矩形,因为数组可能是任何类型,包括数组类型,所以有的数组每一行长短都不等,被称为锯齿数组(有的也叫交错型数组),在声明锯齿数组时,要依次放置左右括号。在初始化锯齿数组时,只在第一对方括号中设置该数组包含的行数。定义各行中元素个数的第二个方括号设置为空,因为这类数组的每一行包含不同的元素个数。之后,为每一行指定行中的元素个数:
int[][] numbers= new int[3][]; //这个锯齿函数中有3个数组
numbers[0] = new int[1]{1}; //第一个有一个元素
numbers[1] = new int[4]{3,4,5,6}; //第二个有四个元素
numbers[2] = new int[3]{7,8,9}; //第三个有三个数组
七.接口
接口:定义一个约定,能够被类或结构实现,接口不提供它所定义的成员的实现,只指定实现该接口的类或结构必须提供的成员,即接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。接口可以包含方法、属性、索引器和事件作为成员。
接口声明的关键字:interface
interface IMyInterface //接口名通常以I开头,默认访问方式是public
{
void MethodToImplement(); //不允许写具有方法体的函数、不能有字段,构造函数
string color { get ; set ; } //接口内可以定义属性(有get和set的方法)
void SetText(string text); //接口成员不能有 new、static、abstract、override、virtual 修饰符
}
除此之外,接口的亮点还支持多重继承,即一个接口可被多个接口,类和结构继承,一个接口,类和结构也可继承多个接口;当类或结构继承一个或多个接口时,必须实现接口中的所有方法。当实现了接口后,该类或结构能被隐式的转化成该接口类型;C#也支持显式接口成员实现,采用的时完全限定的接口成员名,即在实现时用接口名.接口方法(){...};来实现,调用的时候也只能通过接口类型来访问,不能通过类的实例来调用。
八.枚举
枚举:使用enum关键字来声明,是一组命名常数的值类型。与类同级。枚举的成员始终是公共的,不能有访问修饰符。枚举本身的修饰符仅能使用public和internal,默认public。
enum sex //枚举类型的枚举成员均为静态,且默认为Int32类型。也可以修改:enum sex:byte(这样就改变了底层数据类型)
{
male, //默认male=0,可以设置成male=2,这样female=3;也可以male=2,female=5
female //枚举成员不能一样,但枚举值能,male=3,female=3
}
每个枚举类型都有一个对应的整数类型,称为该枚举类型的基础类型,没有显示地声明基础类型的枚举声明以为着所对应的基础类型是Int32类型,枚举类型的值域不受它的枚举成员限制,枚举的基础类型的任何一个值都可以强制转换为该枚举类型;枚举的声明包含常数表达式,用于指定成员的初始值设定,每个枚举成员的常熟之必须在枚举的基础类型的范围之内,如果枚举成员的声明没有显式地指定初始值,则第一个成员被指定为零,下一个加一即可。C#提供类一个类来方便操作枚举,下面给出这个类的常用方法:
还有一种枚举叫标志枚举:标志枚举要在顶部加[System.Flags]特性进行声明。而且枚举支持组合运算。
[System.Flags]
enum sex{...}
九.委托
委托:声明关键字是delegate,用来表示对具有特定参数列表和返回类型的方法的引用。委托将方法处理为实体,使其能被赋值给变量,并作为参数传递。委托只关心这些方法的参数和返回类型是否和它一样。至于委托和事件,可以先去后面网站看看,这里先只介绍概念。
下面的例子也是借用里面的。http://www.cnblogs.com/wudiwushen/archive/2010/04/20/1698795.html(大白话系列讲的委托和事件)
十.特性
C#程序中的类型、成员和其他实体支持控制其行为的修饰符,例如方法的可访问性是通过修饰符public、protected、Internet和private来指定。C#使程序员可以将这种自定义的声明信息附加到程序实体,而且可以在运行时环境中检索到它们,这种附加的声明信息是通过特性指定的。(在看的各位,对不起,我还不会这个,写不出通俗易懂的,还是抄书上说的,菜就是原罪,我正在学习,等学会了再来写)。