【原创】《.NET本质论》读书笔记(一)

类型基础

CLR的Type是可重用抽象体,就是把module再细分的结果。Type的描述存放在CLR的module的元数据中,module里同时存着使type工作的CIL(common intermediate language)或本机代码(machine code).

 

Type的强命名包括三部分:assembly name, namespace prefix, type name.

 

以下记录几个容易混淆的东西。

1、access control

     public是所有类可见

     internal是指在type所属程序集可见

     protected是指type自身和子类可见

     private是指自身可见

其中,internal和protected是可组合使用的。另外有一个sealed关键字,是用来指示此类(或方法)不可被继承(或覆写即override)。

问题:对于父类private的字段,子类中含有这个字段吗?当然有,只是子类不能访问罢了。继承时,类的内存分配是按照field的大小来分配的,子类中当然也有父类private字段,只是不能访问。

 

2、可变参数列表 variable parameter list

    CLR的System.ParamArrayAttribute属性应用到最后一个参数上,指定可变参数列表,当然,类型只能是参数数组定义的类型了。例如:

可变参数列表
public sealed class Dialer {
  public static void DialEm(string message,
                            params string[] numbers) {
    for (int i = 0; i < numbers.Length; i++)
      Util.Dial(message, numbers[i]);
  }
  public static void CallFred() {
    DialEm("Hi Fred!", "310-555-1716", "781-555-9895");
  }
}

 

 

3、嵌套类型 Nested Type

     java中的嵌套类型是跟随所属类进行实例化的,CLR中的嵌套类型是static成员,是不能被逐一实例化的。例如:

Nested Types in C#
namespace AcmeCorp.LOB {
  public sealed class Customer {
    public sealed class Helper {
      private static int incAmount;
      public static void IncIt() {
// legal - methods in nested types can access private
// members of containing type
        nextid += incAmount;
      }
    }
    private static int nextid;
    public static void DoWork() {
// legal - IncIt is public member
      Helper.IncIt();
// illegal - incAmount is private
      Helper.incAmount++;
    }
  }
}

 

4、字段的static、const、readonly关键字

static是说这个字段是type级别而不是object级别的,所以在内存中这个type的所有实例共享这个字段。这个字段是在type被CLR首次加载的时候分配内存的,初始化也在这个时候。

const和readonly字段都是说这个值不能改变、只能赋值一次,不同之处在于:const是编译时就赋值的,readonly则是在运行时赋值。所以const是字面值,而readonly是根据运行时提供值决定的。

 

5、类型初始化函数 .cctor

每个类都有自己的构造函数,这个构造函数体在代码中由new来调用;而每个type都有自己的类型构造函数,这个是CLR加载type时候调用的,我们的代码不能调用。

那什么时候CLR调用这个.cctor呢?本来在加载一个type时就该调用了,但是有一个元数据属性beforefieldinit,如果有这个属性的话,调用.cctor就推迟到第一个static field被引用时才调用。这个beforefieldinit是元数据字段,所以是编译器自己加上的。在.net framework中,当你的type没有.cctor只有ctor时,中间语言编译器就自动在IL中加入beforefieldinit标记了。如下图:

没主动写.cctor时
class Program
    {
        internal static long t1;
        private static int i = 0;//这里有一个static字段被赋值

        //这是.cctor
        //static Program()
        //{
        //    t1 = System.DateTime.Now.Ticks;
        //}

        static void Main(string[] args)
        {
            Program p = new Program();
        }
    }


上面这段代码编译后的IL如下

image

Program类有一个.cctor,而且其IL代码如下,只要没有显式定义.cctor, beforefieldinit属性就会出现。

.class private auto ansi beforefieldinit LinaTest.Program extends [mscorlib]System.Object { } // end of class LinaTest.Program

注意:如果Program类中没有上述代码中的static int i=0 的话,IL中就不会有.cctor了,但是beforefieldinit属性还是有的。说明, 有静态字段初始化表达式才会有隐式.cctor出现(这个是什么原因我还不知道,难道可以没有.cctor吗?)

 

转载于:https://www.cnblogs.com/lina/archive/2010/03/14/1685683.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值