
1.static的静态字段、变量是属于公共类的,静态类不允许有构造方法。
静态字段是属于类的,类的实例不能引用静态字段,只能用类名去引
用静态字段。静态字段是类所有实例所共享的字段,静态方法同静态
字段。
静态类的字段和方法都必须是静态的,而且不允许有构造方法出现。
2.对于常量const的定义必须在声明的时候做一个初始化操作。const
定义的常量默认情况下就是static静态的。所谓的常量就是在初始化
以后不能修改里面的值。
3.固定写法:public static void,顺序最好不要换。
4.加上ref后能存放变量的地址。out关键字也是把变量的地址取出,然
后传递过去。out和ref关键字的区别是变量可以不做初始化就可以传
递地址。
5.object类可以接受所有类型的引用。
6.堆heap存储的是值引用类型,即内存地址。栈stack存储的是数据。
7.装箱操作是将栈空间中的数值转化为堆空间当中的存储区域对象。
拆箱操作是将堆空间中的对象拆箱成栈空间的中的变量。
拆箱操作前要进行装箱操作:如
Circle c=new Cirele(42);
object o =c;
int i=(Cirecle)o;
8.结构体与类的区别:结构体的数据是保存在栈当中,是一种值
类型。类的对象是保存在堆当中,类的引用是保存在栈当中。
结构体中不能定义默认构造方法。在结构体的非默认构造方法中你
必须对结构体中所有的字段进行初始化,否则将报错。
在类中声明字段的同时,你可以初始化字段的值。但是在结构体中
是不可以的。
9.创建数组变量:
int [] pins;
pins=new int[4];
int size=int.Parse(Console.ReadLine());
int[] pins=new int[size];//动态改变数组的大小,通过键盘输入
初始化一个数组变量:
int [] pins=new int[4]{4,5,6,7};
访问数据元素,下标是从0开始:
Console.WriteLine(pins[0]);
遍历整个数组:
for(int i=0;i<4;i++)
{
Console.WriteLine(pins[i]);
}
或者:for(int i=0;i<pings.Length;i++)
即通过.Length属性获取数组的元素个数。
或者使用foreach循环:
foreach(int pin in pins)
{
Console.WriteLine(pin);
}
其中的Pin必须和数组中的元素的类型一致,pin为临时变量。
拷贝数组:
int[] pins=new int[4]{9,3,5,6};
int[] copy =pins;
但是这种方式传递的是数组元素的内存地址,所以只要改变了copy
的元素,其中的内存地址保留的值也会影响到pins的值。
数组其实就是引用类型,其元素具是存储在堆stack当中的。
如果要完全拷贝的话可以使用下面的方式:
int[] copy2=new int[pins.Lenth];
for (int i=0;i<pins.Length;i++)
{
copy[i]=pins[i];
}
foreach(int c in copy)
{
Console.WriteLine(c);
}
以上的方式就是一一对应的方式,另外开辟了内存空间,修改copy2
元素的值的话不会影响Pins元素的值了。和这种用for循环做一一拷贝
的方法完全一致的方法还可以使用以下方法:
pins.CopyTo(copy,0);//copy为拷贝到的数组,0为开始拷贝的下标数。
还可以用:
Arry.Copy(pins,copy,copy.Length);
或者:int[] copy=(int[])pins.Clone();//克隆方法
10.集合类:ArrayList
在使用集合时必须引入命名空间:using System.Collections;
numbers.Insert(numbers.Count-1,5);
numbers.Remove(5);
numbers.RemoveAt(2);//移除指定的元素,2指起下标位置,开始位置为0.
ArrayList存储的都是object类型。
11.params关键字:
注意点:1.不能仅使用params来重载方法。
2.不允许ref和Out同params同时使用。
3.Params数组必须是最后一个参数,当有多个参数的时候。
4.一个没有params的方法的优先级要高于带有params的方法。
5.对于引起歧义的方法重载编译器报错。
12.所有的类的父类都是object类,父类有时也称基类。
子类有时也称作派生类,子类继承父类(即继承了父类中的非私有的
属性和方法。)基类派生出子类。子类与子类之间是没有关系的。
继承的使用:
Class Horse:Mammal
{
public void Trot()
{
}
}
pubilc void GetName()
{
return name;//获取名字字符。
}
在实例化子类的时候调用构造方法时首先调用的是父类的构造方法。
调用基类(即父类)构造方法:
class Horese:Mammual
{
public Horese(string name):base(name)
{
}
}
父类引用可以引用子类的对象。
父类引用只能调用子类继承自父类的方法,父类引用不能调用子类独有
的方法。
子类引用不能直接引用父类对象,除非将父类对象的数据类型强制转换
成子类。但是实际开发过程最好不要使用这种方法,因为语法上没有错
误,但是运行时会报错。
捕获异常的方法:
try
{
Horese newHorse=(Horese) new Mammal("aa");
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
new关键字是子类隐藏继承的父类中的方法。在实际开发中对于New关
键使用比较少。
override是子类重写了父类的方法。比较常用,在一定程度上来讲,
子类继承父类实际上是对父类的继承和扩展,override其实上是对父
类进行改写和拓展用的。
定义override方法的注意事项:
1.virtual和override不能使用在private方法上;
2.重写的方法必须和virtual的方法同名,参数列表一直,返回值类型一致。
3.拥有相同的访问级别
4.只能重写虚方法(即virtual方法)
5.已经用override定义的方法不能在再用virtual定义;
6.在子类中不用override定义父类同名方法,编译器报错,但是你可以用New
关键字重新定义该方法。
父类引用可以调用子类重写父类的方法,而不是调用父类原来的方法。
Protected访问修饰符子类可以访问到父类的protected属性,而外部
类是无法访问的。
扩展方法是根据this后面第一个参数来确定扩展方法的类型的。
13.定义接口:
interface IComparabel
{
int CompareTo(object obj);
}
注:接口名用大写I开头
接口本身是不能实例化的,关键字默认是public的。
class Hores:Mammal,ILandBound,IGrazable
{
}//父类名(Mammal)在钱,接口名在后,只能继承一个父类,但
//可以实现多个接口
14.抽象方法是没有方法体的。抽象方法是不能直接被调用的。
抽象方法默认就是virtural方法。抽象类是没有对象的,不能被实例化。
15.密封类sealed不能够被继承,没有子类的。 也不能在子类中重写的。
16.对象的生命周期:
Square mySquare=new Square();
Square referenceToMySquare=mySquare;
mySqure=null;//当以下这两个变量都为空的时候,mySquare就变为垃圾。
referenceToMySquare=null;
17.析构方法是对象变成垃圾被销毁的时候所调用的方法。
析构方法注意点:
析构方法必须和类名保持一致起形式如~Tally(){};
析构方法只存在于引用类型;
不可对析构方法是用访问修饰符;
析构方法不允许带任何的参数;
在是用IO操作的时候一般是用try ...catch结构,可以防止因为程序出现
异常的时候,后面可以添加释放掉内存的语句。否则异常程序不会释放内存。
Dispose()方法一般是在析构函数中调用的。Dispose其实是一个虚方法。
当一个对象不用的时候,如果还占用内存资源的和当一个对象超过生命周期
的时候必须销毁对象,释放掉占用的内存资源。
18.属性的定义:
struct ScreenPosition
{
private int x,y;
public ScreenPosition(int X,int Y)
{
this.x=rangeCheckX(X);
this.y=rangeCheckedY(Y);
}
public int X
{
get{return this.x;}
set{this.x=rangeCheckX(value);}
}
}
属性的命名规则:将字段的首字母大写,其他的和类一样。
属性的的字段方法只有get和set,里面以分号为结尾。
19.使用索引器:
public bool this[int index]//索引器的名词统统为this
索引器与数组的差别:
first:索引器不仅可以用整形数值做下标,也可以用string类型。
public int this[string name] {...}//It is OK
second:索引器能够像方法一样被重载
public Name this [PhonmeNumber number]{...}
public PhoneNumber this[Name name] {...}
third:索引器不能作为ref和Out修饰的参数
接口当中可以有索引器,但是接口中的索引器是没有内容和大括号的。如:
interface IRawInt
{
bool this [int index]{get;set;}
}
20.定义并使用委托:
class Controller
{
delegate void stopMachineryDelegate();
private stopMachineryDelegate stopMachinery;
public Controller()
{
this.stopMachinery+=folder.StopFolding;
//以上语句相当于:
//this.stopMachinery=
//new stopMachineryDelegate(folder.StopFolding);
}
委托有些书又叫函数指针,而其中的函数即是C#中的方法,
指针对应着C#中的引用。
委托其实也是一种数据类型。
委托的实例化:委托变量名=new 委托类型(方法名);
从委托中移除一个方法:
stopManchinery-=welder.FinishWelding;
//从委托中移除委托并没有指向的方法,委托并不会抛异常。
21.Lambda表达式:
一个典型方法包括:返回类型、方法名、参数列表、方法体,
Lambda表达式包含两样参数列表和方法体,返回值类型是根据
Lambda使用时的上下文由编译器推断出来的。如:
(()=>{folder.StopFolding(0);});
//其中=>是告诉编译器,此表达式为Lambda表达式。
22.事件的声明和委托的声明和初始化是一样的,没有什么大区别。
23.创建范型的方法:
public static void swap<T>(ref T a,ref T b)
{
}
24.协变接口与逆变接口概念(前提是范型接口)
逆变接口的定义:
public interface IComparer<in T>
{
int Compare(T x,T y);
}