zoukankan      html  css  js  c++  java
  • <<Clr Via C#>> Key Points (1) (46章)

    .net框架那本书已读过几遍,但仍有一下地方的知识被遗漏.
    重读此书,主要摘录了<<Clr Via C#>>中有些自己不知,或容易忽略的技术要点

    前1-3章未读先跳过了

    第4章

    1) 认为GetHashCode不应该定义在Object类中,因为大多类不会在Hash Table中当key使用.应该设计成一个Interface,当需要做key时,去实现这样的interface就好了

    2) CLR创建对象时都需要使用New操作符. (应该不全是,在后面的章节中有提到)

    3) New操作符做了哪些事:

      1. 计算对象实例需要的内存空间.类自身定义的fields以及基类定义的fields,附带两个额外的成员: a.指向类型的指针 b. 用于同步的index(sync block index, 用于管理对象)
      2. 分配内存,将所有字节付0
      3. 初始化两个额外的成员
      4. 调用实例构造函数.
      5. 返回一个地址指针给变量

    4) 实例构造函数会依次先调用基类的无参构造函数,每个构造函数负责初始化自身定义的Fields

    5) CLR是类型安全的,所以在运行时总是知道对象的确切类型

    6) CLR根本就不知道namespaces的存在,因此当它需要访问一个类型时,它需要知道此类型的完整名字.这点可以通过ildasm.exe工具查看生成的IL代码.所谓的别名也只是告诉编译器如何得到类型的完整名.

    7) 一个thread被创建,会为其在stack上分配1MB空间.此空间用于传递参数,创建局部变量等.

    8)

    第5章

    9) 应该为值类型重写Equals方法.因为ValueType是通过reflector实现Equals方法的,严重影响性能

    10) C#编译器不允许值类型实现Finalize方法

    11) System.Runtime.InteropServices.StructLayoutAttribute可以为类声明字段的布局方式

    12) 如何在AppDomain里生成唯一的ID: 通过System.Runtime.CompilerServices.RuntimeHelpers类的GetHashCode()方法

    13) ValueType实现GetHashCode使用reflection以及XOR一些字段.(实际上不完全是这样.应该是返回第一个不为null的field的hash code)

    第6章

    14) Friend Assemblies : 一般来说类型定义为internal访问权限的话,此成员只能被同一assembly其它类型访问.但由于某些特殊原因, 特定的另一个assembly成员想要访问次internal成员类型,那么就可以使用此技术

    Using System.Runtime.CompilerServices

    [assembly : InternalsVisibleTo(“assembly name, assembly key”)]

    15) 子类型想要覆盖父类型的成员时, 在C#里他们的访问权限定义的必须一致.在CLR里,子类型还可以降低访问权限.

    16) Static Class : 一直没注意原来C#也有静态类型.

    静态类型约束:

          Ø 此类型必须直接继承自Object.因为此类型没有实例,所以继承自其它类型没有任何意义.

          Ø 不能实现任何interface

          Ø 只能定义静态成员

          Ø 此类型不能被用于私有成员,方法参数,局部变量.

    17) 一般来说对于非虚方法使用call指令,对于虚方法使用callvirt指令.callvisrt指令会去检测当前对象是不是null,而且还需要查表,因此会慢一点.

    object o = new object();

    Type t = o.GetType();

    查看IL却发现实际上是使用callvirt指令的,为何呢?这是C#编译器为了保证o对象不为空,因为callvirt指令会去检测o对象是否为null,而call指令不会.当JIT发现callvirt指令调用方法时,发现此方法不是虚方法,就会调用它的非虚方法,不需要再去查表.

    18) 有时候编译器也会用call指令代替callvirt指令去调用虚方法.例如调用对象的ToString()方法.如何用callvirt指令去调用,会出现死循环(??why)

    19) 优先使用非虚方法:

          Ø 调用虚方法要慢

          Ø 虚方法不能被inline

          Ø 虚方法使得版本控制更复杂

    20) Jeff认为除了sealed之外应该增加closed来修饰class,子类不可以修改父类的任何行为,但可以扩充.

    21) 当事情变得越来越负责的时候,添加更多的类

    22) 标记一下: 字段前面还可以加volatile修饰, 表示字段可能被多个并发执行线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。

  • 相关阅读:
    请多指教
    第九周作业总结
    win10系统开机输入密码黑屏解决方法
    第八周作业总结
    第七周作业总结
    第六周作业总结
    第五周作业总结
    第四周作业
    第三周作业
    2019年春季学期第二周作业
  • 原文地址:https://www.cnblogs.com/anders06/p/778845.html
Copyright © 2011-2022 走看看