c#构造器的一点理解(三)

来源:互联网 发布:ubuntu 163源 编辑:程序博客网 时间:2024/05/01 22:35

本章的重点是   类型构造器

本人的疑问 :
1 类型构造器是初始化类型的初始字段的,那么实际的应用场景是什么那?
2 在类型中,静态构造器,以及静态字段是用来做什么的那。
3 静态构造器在值类型和引用类中中非别如何使用,如何理解那!

下边的几个知识点是从书中(clr via c#)看到的
1  编译器不默认生成静态构造器,如果显式的生命,那么类型构造器只能生命一个static 的,private的,无参的构造器。  当类型第一次被访问的时候调用。
2 类型构造器只能是private的, 但是不能显示指定修饰符,如果指定了会报错,这样做的目的是为了防止程序员修改其访问属性。
3 值类型也可以声明类型构造器,但是不要这么做,因为值类型的类型构造器有的时候是不别调用的, 例如生命诚数组的时候 ?
那么为什么引用类型肯定会存在调用类型构造器的情况 ?    -- 因为引用类型的数据类型,必须被实例化才能使用,如果没有实例化,那么就不能使用 ? 不知道这么理解是否正确。
4  类型构造器只能别执行一次。如果是多线程程序,那么如何保证类型只被执行一次。 
这种情况需要一个互斥的相称同步锁 ? 这个代码是手工实现,还是clr已经实现了 ? 以后研究。
5 类型构造器可以实现单例模式。
6 类型构造器 不能互相引用,这样是错误的方法, 意识就是classa的类型构造器 和classb的类型构造器不能互相引用。
7 类型构造器如果有异常,那么这个类就不能使用。 代码如下:
 sealed class baseClass    {        public void Test()        {Console.WriteLine("基类") ;          }static baseClass()  //只能是无参,statci的,private的,但是private还不能显示指定。 {throw new Exception("")   ; //有这句代码,使用类型的的时候就报错 ,意思也就是类型构造器不能有错误,有了错误,那么整个类型就不能使用了。Console.WriteLine("类型构造器") ;  }    }
类型构造器的常规用途就是初始化 静态字段。
而且提供了一种简便的语法结构。
private static Int32 i = 5 ;   //值类型中的字段是不能使用这种结构的,但是值类型的静态字段是可以这么用的。
struct someTypa{static int a = 5 ;}
但是  
struct someTypa{ int a = 5 ;}
这么些就是错误的  为什么那 ? 因为第二种情况是值类型无参构造函数的写法,但是值类型又不允许有无参构造器。所以是错误的
第一种情况为什么是正确的那 ? 类型构造器本身就是为了处理静态字段而生的,所以这么做是正确的。 -- 融会贯通了,很多东西都是很好理解的,哈哈,我入门了,oye

8  类型构造器不应调用基类的类型构造器,因为没有继承基类的静态字段 ?  类型的静态字段不能被继承 ?
我的理解是,因为类型构造器是private的,所以不能被继承。
9  当访问类型构造器的时候同时能访问所以基类的类型构造器。 类型实现的接口也需要访问类型构造器  ? clr不支持这个做饭。
10 卸载类型的时候执行一些代码  clr同样不支持。但是可以使用变通的方式来实现 ?
9 10 两种情况,以后慢慢研究。
下边的代码 是上边情况的验证代码 以及注释 :
using System;using System.Data;using System.Text;namespace  myStu{/*值类型   最好不要定义类型构造器引用类型可以定义类型构造器,但是只能是一个。本程序主要是为了加深类型构造器而写的一个学习用的程序。*/class programe{   static void Main(string[] arg){try{                 sonclass  obj = new sonclass() ; //首先调用类型构造器。//还有一个疑问,为什么这里还要调用父类的类型构造器//是否可以这么理解,//首先的调用子类的类型构造器,//然后调用基类的实例构造器钱,这个时候出发了 基类的类型构造器。//调用基类的实例构造器//调用子类的实例构造器  . 能把这句话搞清楚就说明你进步了。哈哈obj.Test() ;sonclass  obj1 = new sonclass() ;//这里就不调用类型构造器了。  obj1.Test() ;}catch (Exception err){Console.WriteLine(err.Message);}}}    class baseClass    {public  static Int32 i = 5 ;        public void Test()        {Console.WriteLine("测试的动作") ;          }public baseClass(){Console.WriteLine("基类的实例构造器");}static baseClass()  //只能是无参,statci的,private的,但是private还不能显示指定。 {//throw new Exception("")   ; //有这句代码,使用类型的的时候就报错 ,意思也就是类型构造器不能有错误,有了错误,那么整个类型就不能使用了。Console.WriteLine("基类的类型构造器") ;  }    }class sonclass :baseClass{static sonclass () {Console.WriteLine("子类类型构造器") ;  }public sonclass(){Console.WriteLine("子类的实例构造器");}}struct someTypa{static  int a = 5 ;}}


类型构造器的调用 以及性能问题

1 类型构造器的调用是线程安全的。 只能被调用一次。 这些的实现是有clr来决定的。
2 什么时候类型构造器可以被调用。
     精确语义  : 引用类型被实例化之前
   访问非继承成员和字段之前(这种情况应该是不调用构造函数就有了类型实例的情况)。
    字段初始化钱语义
访问非继承静态字段之前被访问。

做好的方案当然是是用第二种情况了,但是在c#我们怎么决定是使用第一种情况还是使用第二种情况那, 
这个可以通过隐式实现类型构造器,或者是显示实现构造器来进行区别,这个是在c#层面说的,
                在clr层面来说,是在元数据表中是够调价  beforSatticfielsini 标记来进行区分的。
   这里现在还不是很明白,需要以后在进行详细研究。




















原创粉丝点击