你必须知道的.NET读书笔记分享——(5)关键字详解
1、new
· 创建对象和调用构造函数;
· 向基类隐藏继承成员;
1 class Number
2 {
3 public static int i = 1;
4 public virtual void Show()
5 {
6 Console.WriteLine("base class");
7 }
8 public virtual void ShowNumber()
9 {
10 Console.WriteLine(i);
11 }
12 }
13 class IntNumber : Number
14 {
15 new public static int i = 2;
16 public new virtual void Show()
17 {
18 Console.WriteLine("derived class");
19 }
20 public override void ShowNumber()
21 {
22 Console.WriteLine(Number.i.ToString());
23 Console.WriteLine(i.ToString());
24 }
25 }
26 class Test
27 {
28 static void Main(string[] args)
29 {
30 Number n = new Number();
31 n.ShowNumber(); //1
32 IntNumber intNum = new IntNumber();
33 intNum.Show();//derived class
34 intNum.ShowNumber();//1,2
35
36 Number num = new IntNumber();
37 num.Show();//base class
38 num.ShowNumber();//1,2
39
40 Console.Read();
41 }
42 }
· 指定泛型类声明中的任何类型参数都必须有公共的无参构造函数;
· new一个class时需要在托管堆中分配内存,然后调用构造函数来实现对象初始化;
· new一个struct时调用其构造函数,完成实例的初始化;
· new一个int时则初始化其值为0。
2、base
· 调用基类上已被其他方法重写的方法;
· 指定创建派生类实例时应调用的基类构造函数;
· 在重载的情况下,base指向直接继承的父类成员的方法,没有重载时则其可以指向任何上级父类的公有或者受保护的方法。
3、this
· 访问本类的非静态成员;
· 限定被相似的名称隐藏的成员;
· 将对象作为参数传递到其他方法中;
· 声明索引器。
4、using
· 引入命名空间
· 创建别名
· 强制资源清理(用于实现了IDisposable接口的类型)
· using适用于清理单个非托管资源的情况,清理多个非托管对象最好用try-finally实现
· 支持初始化多个变量,但条件是这些变量的类型必须相同:
如:using(Pen p1 = new Pen(Brushes.Black), p2=new Pen(Brushes.Blue)) { //... }
变通的方法时针对接口:using(IDisposible font = new font("Verdana",12,FontStyle.Regular), pen = new Pen(Brushes.Blue)) { //... }
· using中初始化的对象,可以再using语句之前声明:
如: Pen p1 = new Pen(Brushes.Black); using(p1) { //... }
5、class和struct
· class是引用类型,继承自System.Object类,struct是值类型,继承自System.ValueType
· class侧重于行为表现,struct侧重于数据存储
· class支持继承,可继承自类和接口,struct不能从类继承,但是可以继承接口
· class可以声明无参构造函数,析构函数,struct则只能声明带参数的构造函数,且不能声明析构函数,其没有默认无参构造函数,默认无参构造器只能简单地把所有值类型初始化为它们的0等价值
6、ref和out
· 使用ref和out关键字则表示参数按引用传递,此时传递的是参数的地址,也就是实例的指针;
· 不允许通过区别ref和out来实现方法的重载;
· 使用ref的参数必须是一个实际的对象,不能指向null,而使用out参数可以接受指向null的对象,然后在调用方法内部必须完成对象的实体化。
7、is和as
· is返回结果为true或false,且不会抛出异常,如果对象为null,则返回值永远是false
· as在对象不兼容时返回null,若结果判断为null,则会抛出NullReferenceException异常
· 通常is用于对象判断,as用于类型转换
8、const和readonly
· const是常量,确定于编译期,readonly是只读变量,确定于运行期
· const在定义时必须指定初始值,readonly和static readonly在声明时可以指定也可以不指定初始值,同时可以在构造函数中指定初始值
· const只能应用在值类型和string类型上,不能用new初始化一个const常量,因为new总是在运行时才能确定,readonly可以定义任意类型,但是对引用类型字段来说,其不能限制对该对象实例成员的读写控制
· const可以定义字段变量和局部常量,而不能给局部变量使用readonly定义
· static readonly字段的初始化,必须在定义时或者静态无参构造函数中进行
· const和static readonly定义的常量只能有类访问,而readonly定义的常量是非静态的,只能由实例对象访问
9、params
· 实现可变数目参数;
· 其修饰的参数必须为一维数组;
· params修饰的参数数组,可以是任何类型;
· params必须在参数列表的最后一个,且只能使用一次。
10、yield
· 用于迭代器块中,用于向枚举器对象提供值或者发出结束信号,其中yield return用于依次返回每个元素,而yield break用于终止迭代。
11、lock
· lock的对象必须是引用类型参数
· 避免锁定公共对象或不受应用程序控制的对象实例,最好是定义private对象来锁定
· 不建议锁定字符串类型对象,因为其对多线程操作是安全的
· 让两个线程以相同的加锁顺序锁定对象,是避免死锁的有效手段
· Monitor类的TryEnter方法可以有效防止死锁的发生
· 锁定对象对性能存在影响:一方面是加锁与解锁的系统开销,另一方面可能导致其他线程因为等待释放对象而暂停执行