1、语句
语句是c#中的一句话,通常以分号结束。
语句有条件语句和循环语句。
条件语句有if  switch
循环语句有whiledo。。。whileforforeach。值得注意的是forforeach的一点区别:在for循环中,可以对其数组进行修改;而foreach是只读的,不能修改。
另外,还有一些特殊的语句,比如:break;跳出循环,continue;结束本次循环,return;可以返回值,也可以结束程序的执行。Throw;抛出异常。
2、结构
结构式封装了一些儿小型的相关变量组,这些变量的类型是可以不相同的。结构呢,是属于值类型的。它不能够被继承,但是可以实现接口。结构的访问修饰符只能是publicinternal这两种,是不能用protected的。
结构是可以赋值为null的,这与其它的值类型不太一样,如果值类型想赋值为null的话,则要加?号才行。
说道结构,就要说一说结构和类之间的区别了。在结构中,如果重载构造函数,系统默认的无参的构造函数也是存在的,而类中这个默认的构造函数是会被新的构造函数所代替的。还有,在结构中,一旦有构造函数,那么,所有在结构中声明的字段(除了常量和静态的),都是需要在构造函数中赋值的(成员是不能自己给自己赋初值的,只能在构造函数中),而类中是根据需要来赋值。
最后就是结构中,如果实例化时,是可以不用new关键字的,如果用new关键字来调用的话,系统会默认的赋初值的,若不用,则必须先给其赋值,然后使用;而类中只能通过new来调用。
3、枚举
枚举是有一组称为枚举数列表的命名常量组成,它是将某一系列的类型统一放到一起,这样,我们使用起来就方便了。
特点:每种枚举类型都有基础类型,该类可以是除char以外的任何整型。枚举元素的默认基础类型为int。默认情况下,第一个枚举数的值为0,后面每个枚举数的值依次递增1。还有,枚举的每个元素都是一个常量。
属性枚举:(Flags)用于枚举的或运算
4、值类型、引用类型
值类型,是放在线程堆栈中的,调用时传递的是值,这样,不管新值是否发生变化,都对新值没有影响。常见的值类型有三种:简单类型、枚举类型、结构类型;
引用类型,他存储的是一个引用,在托管堆中存放,在调用时传递的是地址。因此,不管把引用类型的赋给谁,对他们的修改,实质上都是对同一个地址进行的操作,所以,其结果是会发生变化的。常见的引用类型有:类类型、接口类型、Unicode字符串、数组类型、委托类型。
5、装箱、拆箱
装箱:就是将值类型转换为引用类型的
拆箱:就是将引用类型还原为值类型。
说明:在我们平时写代码的过程中,我们会经常地进行装箱和拆箱的操作,这样会大大降低程序的执行效率,所以,我们要尽量的避免装箱和拆箱的操作。
6、String、StringBuilder
String是一个不可变的顺序字符集,可以直接赋值来构造,不用new的。
String一旦定义,就不可变,如果发生变化的话,就会重新生成性的字符串,原来的就会变成了垃圾。如果字符串相同的话,可以共用一个字符串,这是传说中的字符串留用。
StringBuilder也是用来存储字符集的,但是它是可变的。
它是在System.Text这个命名空间中,每次分配char类型的数组的长度,只有调用ToString()这个方法后,才会重新分配内存。
7、数组
Array是所有数组的父类,在这个类中,提供了创建、操作、搜索和排序数组的方法,用CreateInstance(Type, Int32)可以来实例一个数组。
数组共分为以下几种:
一维数组:如int [] arr=new int[2]{1,2};
二维数组:如int [,] arr=new int[2,2];
交错数组:如int [][] arr=new int[][];
说明:交错数组时元素为数组的数组。交错数组元素的维度和大小可以不同。
8、集合
集合时一组组合在一起的类似的类型化对象。内部是用数组来存储信息的。
集合一般都是动态的,这样我们就可以动态的添加元素。
比较常用的有ArraylistList
Arraylist,来自命名空间System.Collections;它通过Add()方法来添加数据,可以用名称[0]来取;
如:Arraylist al=new Arraylist();
如果在这指定长度,则这个长度指的是容量,并不是集合里面数据的长度(该长度一般用Count来取),它的默认长度是4,超过后就要翻倍:4,8,16。。。
泛型list的用法和Arraylist差不多,但是泛型用起来要比Arraylist要好用,推荐使用泛型。
9、类
类是一组具有相同数据结构和相同操作的对象的集合。类是对一系列具有相同性质的对象的抽象,是对对象共同特征的描述。
类中的成员可以有字段、方法、属性、索引器、事件、委托
说到类,就不得不说一说oop,面向对象的思想,说白了,就是我们在编程时,要用人类的思维去考虑问题,把相同的数据结构和操作抽象成类,然后对其进行操作。
面向对象有三大特点:继承、封装、多态。这三大技术都是通过类类实现的
10、方法参数(ref,out,params
Ref out的操作对象都是值类型的数据。它们可以将值类型的数据临时的当引用类型的来用。
Ref是能进能出。什么意思呢,也就是说,我们可以将已经赋了值的变量,通过加上关键字ref,将其整个变量的名称和值一同带进方法的内部进行操作,完了之后,还可以将这个变量的最终结果给带出来。
out的能力就有点小了,out只能将这个变量的名称带进去,之后,在方法中要先对其赋值,然后进行相应的操作,最终将其结果带出来。总结一下,就是out只能出。
Params是一个动态的参数。范围(0n
也就是说,我们在定义方法的时候,并不知道要传进去的参数的个数,这个时候,就可以通过定义Params这个动态的参数了。
11、分部方法,扩展方法,匿名方法
分部方法,通过partial关键字来实现。
一般是用于分部类中的,但是这两个类的签名必须是一样的。这样,我们就可以实现在一个类中只定义方法的签名,供我们来使用,而在另一个类中,可以有别的人来实现它。
注意:1 分部类必须在同一个命名空间
2、分部方法不能有访问修饰符的
 
扩展方法,就是针对一些系统类,我们需要来添加一些方法供我们使用,但是,由于是系统自定义的,我们肯定是看不到源代码的,不能直接对其修改,这样,扩展方法就出场了。
定义:扩展方法必须在静态类中定义
而且,扩展的方法也必须是静态的,方法中的参数用this关键字加上要扩展的类名 
匿名方法:通常用委托来定义。
12、构造函数
构造函数:分为实例构造函数、私有构造函数和静态构造函数。值得说明一点的是静态构造函数,只要是声明了一个类的对象,就会自动调用这个静态构造函数,而且只在第一次声明的时候调用。
说道构造函数,就不得不说一下析构函数,首先,析构函数是针对类的,在结构中式没有析构函数的,再者就是,一个类中只能有一个析构函数,析构函数是不能继承和重载的,而且析构函数是没有修饰符和参数的,同时,析构函数是系统自动调用的,也就是说,我们是无法自己来调用析构函数的。
13、字段、属性
字段是类或结构中的对象或值,雷和结构可以使用字段来封装数据。一般字段的声明都是private的,不建议使用public。还有就是,字段的初始化要在调用对象实例的构造函数之前。如果构造函数为字段已经赋值了,那么,我们再对字段赋值,都是无效的。
我们还可以将字段声明为readonly,这样,这个字段就是只读的了。
属性:是一种封装字段的技术,这样,我们就可以灵活的去控制这个字段的读写权限了。
属性中有getset两个访问器。通过value关键字来对其赋值。
14、索引器
索引器:允许类或结构的实例就像数组一样来访问。索引器的定义类似于属性,不同之处是索引器使用了this关键字来访问。
索引器可以有多个形参,就像二维数组一样。
一般的,使用索引器的话,都可以用泛型的技术来实现。
15、委托
委托:是一种承载方法的,这个方法可以有多个。方法有实例方法,静态方法,回调方法(异步),我们可以把委托想象为父类,而承载的方法是子类,也就是说,子类通过重载实现了父类的方法。这样,我们就知道,方法不必与委托签名完全匹配的。
委托是和类一个级别的,因此,委托可以定义到类的外面,亦可以在类的里面。
使用委托的步骤:
1、  定义委托
2、  定义方法
3、  New委托,将方法赋给委托(在这里,new有两个功能,一个是分配内存空间,二是完成指针的功能。
委托的协变和逆变:它们的本质都是子类型赋给父类型。不同的是,协变的赋值对象是返回值,而逆变的赋值对象是参数
特别注意的是:给委托赋值时,方法名一定不能加括号(如果有括号,就成了调用了)。
16、事件
事件:可以理解为类与类之间发出的通知,到收到通知后,进行相应的操作。
我们把发送事件的类称为:发行者
把接收或处理事件的类称为:订户
它们之间的关系是这样的:一个事件可以有多个订户,一个订户可以处理来自多个发行者的多个事件。
事件是基于EventHandler委托和EventArgs基类的,为啥这么说呢,对拉,一般事件都要靠委托来实现的。
17、静态类,密封类,抽象类
静态类:声明为静态类的话,这个项目中,只会有一份,没有副本。静态类中调用成员时都是 类名加成员
静态类特点:
仅包含静态成员;
不能被实例化;
是密封的;
不能包含实例构造函数。
密封类:用关键字sealed来定义类。
密封类不能用作基类,所以,他不能是抽象的。密封类主要用于防止派生。
抽象类:用abstract关键字
抽象类时不能实例化的,其成员是不能有抽象字段的,抽象的方法和字段都不能赋值。
抽象类是可以被继承的,一旦定义了抽象的方法、属性、索引器、事件,那么子类要是想重新覆盖,必须使用关键字override
实例化继承的抽象类时,要将抽象类中所有的抽象成员实例化
注意:
1、  抽象类可以继承和那个抽象类,但是可以不实例化其抽象成员。
2、  如果构造函数有参数的话,必须继承
3、  抽象类也可以继承实例化类
18、接口
接口是一种类似与抽象类的功能,用interface关键字来声明。接口与抽象类不同的是:
1、  任何非抽象类型,如果继承了该接口,那么子类都必须实现接口的所有成员
2、  接口中的成员都只能声明,不能够实现的(抽象类中的抽象方法是可以实现的)
3、  接口中的成员一共有四种:方法、属性、事件、索引器。
4、  接口中成员的访问修饰符只能是public,而且,在声明的时候,是不允许写出public的,系统会默认的添加
接口是支持多重继承的,也就是说,类和接口可以从多个接口继承,同时,接口自身也可以从多个接口继承。
19、虚方法、重载方法
虚方法:用virtual关键字来声明
一般用于继承,如果要覆盖虚方法,那么必须用override关键字。
重载方法:
有时候,我们在定义方法的时候,对于同一个方法,我们可能会有不同的需求,这就用到了重载方法了。
每个类型成员都有一个唯一的签名。方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成。只要签名不同,就可以在一种类型内定义具有相同名称的多种方法。
20、继承
继承:类可以从其他类中继承,这样,子类就拥有了父类的一些方法和属性等;
如果子类想覆盖父类的方法,则必须在父类的方法中用virtual关键字声明,然后在子类中用override关键字来覆盖;
如果子类要定义一个与父类具有相同的方法签名的方法,那么,可以使用new关键字显式的隐藏父类的方法(如果没有new的话,会隐式的隐藏)
21、访问修饰符
访问修饰符很多,在这里,我们只介绍一些常用的:
Private   私有的,一般只能在类的内部使用,它的作用增加了成员的安全性
Public  公有的,也是我们最常用到的,它可以在整个项目中都可以访问到
Protected 受保护的,一般用于继承,只能是其派生类可以访问
Internal  内部的   ,它的作用范围是整个程序集
protected internal   在同一个程序集中能够访问到,出了这个程序集后,只能在子类中才能访问到