CLRvia3读书笔记

​​​​​​​

即刻关注,获取更多

// 第1章 CLR的执行模型
1.CLR Common Language Runtime 公共语言运行时
2.托管模块 managed module 托管模块各部分(PE32或PE32+头、CLR头、元数据(metadata)、IL(中间语言)代码) [PE=portable Executable]
3.类型库(Type Library) 接口定义语言(Interface Define Language)
4.%SystemRoot%System32  目录中 MSCoreEE.dll 判断.net framework是否安装
5..NET Framework SDK CLRVer.exe -all 可以列出所有版本
6./platform 开关 (anycpu[默认],x86,x64,Itanium)  WoW64(Windows on Windows64)技术允许32位的windows应用程序,在64位上运行
7.ILAsm.exe 汇编器,ILDasm.exe 反汇编器
8.JIT Compiler Just-in-time 即时编译器
9./optimeze /debug 开关 涉及 IL优化和JIT本地代码质量优化(pdb文件[Program Database])
10.PEVerify.exe查看不安全代码
11.本地代码生成器 NGen.exe
12.通用类型系统CTS(Common Type System) [包括字段Field,方法Method,属性Property,事件Event]
13.CLI Common Language Infrastructure 公共语言基础结构
14.CLS Common Language Specification 公共语言规范
15.(与非托管代码的交互)Type Library Importer 工具和P/Invoke Interop Assistant 工具源代码 http://CLRInterop.CodePlex.com
// 第2章 生成、打包、部署和管理应用程序及类型
1.csc.exe 命令行工具使用 cd /d C:\Windows\Microsoft.NET\Framework\v4.0.30319  csc /? 查看帮助
2.C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.rsp  rsp响应文件  格式(csc.exe @xxx.rsp xx1.cs xx2.cs)
3.AL.exe 命令行,用visual studio 命令行进入使用
4.配置文件 runtime 节点的使用,可以先从配置文件加载dll, 测试目录可以以 ; 分割




// 第3章 共享程序集和强命名程序集
1.FCL Framework Class Library
2.SN.exe 命令行用法
3.GAC Global Assembly Cache 全局程序缓存集
4.GACUtil.exe 命令行用法
5.延迟签名
6.参看配置文件




// 第4章 类型基础
1.所有类型都是从 System.Object派生,Object public protect static 方法
2.is  as 关键字
3.using AliasName=System.Text.StringBuilder;
4.外部别名 (extern alias), 1.csc /r 命令行 2.选中程序集,查看属性,修改别名
5.线程栈 与 托管堆(类型对象指针,同步索引块,静态字段 and 其他)




// 第5章 基元类型、引用类型和值类型
1.基元类型(primitive type),基元类型可以直接映射到Framework类库(FCL)中存在的类型
C#基元类型 FLC类型 CLS是否相容 说明
sbyte System.Sbyte 否 8位
byte System.Byte 是 8位
short System.Int16 是 16位
ushort System.UInt16 否 16位
int System.Int32 是 32位
uint System.UInt32 否 32位
long System.Int64 是 64位
ulong System.UInt64 否 64位
char System.Char 是 16位Unicode字符(C++中是8位)
float System.Single 是 32位
double System.Double 是 64位
bool System.Boolean 是 1个true false 值
decimal System.Decimal 是 128位
string System.String 是  
object System.Object 是  
dynamic System.Object 是  跟object一样


2.checked unchecked 基元类型操作,也可以对代码块操作,也可以在项目属性中设置(生成,高级,检查上溢出,下溢出操作)
异常:System.OverflowException
System.Numerics.BigInteger(可能抛出 OutOfMemoryException) / Decimal CLR认为不是基元类型,所以checked unchecked对其不起作用
3.引用类型 值类型
值类型:结构(struct)或枚举(enum), System.Eum 抽象类型<-- System.ValueType <-- System.Object
引用类型:class
4.Equal GetHashCode 重写时一起重写,否则会给出警告
5.值类型的两种状态:unboxed 未装箱,boxed装箱 [装箱后为引用类型,引用类型垃圾回收需要调用 Finalize,值类型不需要]
6.CLR如果控制类型中字段的布局[System.Runtime.InteropServices.StructLayout(LayoutKind.Auto)] 
7.对象的相等性(Equal,有些需要重载)与同一性(GetHashCode,Object 静态方法 public static bool ReferenceEquals(object objA, object objB)) 
8.对象哈希码(GetHashCode可以重写,System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(new object()) 获取唯一的hashcode)
9.dynamic(可以用局部变量,字段,参数) var(只能用在声明方法内部局部变量) 




// 第6章 类型和成员基础
1.类型中的成员:常量,字段,实例构造器,类型构造器,方法,操作重载符,属性,事件,类型
2.友元程序集 using System.Runtime.CompilerServices;
  [assembly:InternalsVisibleTo("Wintelllect,PublicKey=222...222")]
3. CLR术语 C#术语
Private private
Family protected
Family and Assembly 不支持
Assembly internal
Family or Assembly protected internal
Public public
4.partial
5.面向对象编程(oop:Object-Oriented Programming) 组件软件编程(csp:Component Software Programming)
代码访问安全性(Code Access Security,CAS) 
6.major version:minor version:build number:revision 主版本号:次版本号:内部版本:修订号
7.abstract virtual override sealed new(用在方法上 表示跟父类没有关系)
8.call IL指令调用静态方法,实例方法和虚方法(快,无需检查类型是否为空,不抛出异常)
  callvir 调用实例方法和虚方法,不能调用静态方法(慢,会抛出 NullReferenceException)
9.new virtual override




// 第7章 常量和字段
1.非基元类型 (const)常量初始值须设置为 null,C#不允许常量指定static关键字,因为常量总是隐式为static
static readonly 可以搭配使用
2.字段
CLR术语 C#术语
Static static
Instance 默认
InitOnly readonly
Voliatile volatile(编译器.clr,硬件不会执行一些"线程不安全"的优化措施)
3. readonly 引用类型,不可以变得是引用,字段是可以改变的




// 第8章 方法
1.class 默认无参构造函数,一旦有构造函数,clr就不生成 无参构造函数了. 见 SomeType1
2.私有变量 赋值过的,会在"每个构造函数"中初始化,如 SomeType2, 更好的方法是显示调用构造器,如:SomeType22(一旦显示调用任意构造函数,那么就不会初始化变量了)
3.值类型, C#不允许定义无参构造函数, CLR允许,但是CLR默认不调用构造函数,必须手动调用
4.类型构造器(静态构造器) 引用类型见 SomeType1   ,值类型见SomeValueType 中Point(不会被调用)
5.类型构造器的性能:初始化的时机  见 BeforeFieldInit,(public auto ansi beforefieldinit) beforefieldinit 标示,告诉CLR提早初始化好静态字段
6.操作符重载操作符重载,实际是生成固定特殊 形如:op_....,而且限制诸多
7.转换操作方,主要是看 函数签名,是否有"装箱,拆箱"  static implicit operator(){} (隐式声明)  static explicit operator(){}(显式声明) 关键字
8.扩展方法 (ExtensionAttribute) 该类 在 System.Core.dll,当一个类 被 this 标识的时候会加这个Attribute
扩展接口,扩展委托的一个demo 见:ShowItemDemo
9.分部方法 partial 标记类(把类分开), 标记方法, 可以只有声明,如果被调用,则IL不会生成相应代码,有实现的时候就会生成
10.
// 第9章 参数
1.Class1 演示了可选参数和命名参数,参数的计算顺序都是从左到右,ref out 不能设置默认参数
默认参数的Attribute:System.Runtime.InteropServices.OptionalAttribute
默认值Attribute:System.Runtime.InteropServices.DefaultParameterValueAttribute
2.ref out 也算一种重载,但是二者只能用一个; 且两个关键字参数类型必须一致,见 Class1.Test
3.利用泛型解决 ref,out 类型一直问题,见SomeMethod,下面是系统的例子
//System.Threading.Interlocked.Exchange()
     //System.Threading.Interlocked.CompareExchange()
4.params 标记 System.ParamArrayAttribute ,会造成一定的性能损失,所以参见 System.String 的 Concat方法怎么实现
5.参数返回类型 IEnumerate (接口,弱类型),IList(强类型),List
Stream, 不用 FileStream,NetworkStream,MemorySteam
参数有用不同的规则,所以要看情况
// 第10章 属性
1.属性(property),无参属性(parameterless property),有参属性(parameterful property),索引器(indexer),匿名类型和System.Tuple
2.数据封装(data encapsulation),访问器(accessor)
3.get set IL默认生成 get_xx set_xx 方法
4.自动实现属性 Automatically Implemented Property(AIP)  Name {get;set;}
5.属性不能 out ref 传参
6.属性方法可能花费更长的时间来执行(执行线程同步,可能造成线程永远终止),所以 可以远程访问的类(System.MashalByRefObject 派生类)不应该用属性,而应该使用方法
7.LINQ Language Intergrated Query,语言集成查询
8.System.Tuple 类型, dynamic e=new System.Dynamic.ExpandoObject(); 实际是一个 IDictionary<String,Object> 对象集合
9.有参属性(parameterful property),System.Drawing.Imaging.ColorMatrix 类提供了多个参数的索引器
10.IL 生成索引器的操作集合是 Item 也即 get_Item set_Item,用 IndexrNameAttribute 更改, 多个索引器的名称必须一致
11.有参,无参属性都IL成方法,所以 System.Reflection.PropertyInfo 类可以发现
12.属性访问器采用内联(inline),把代码直接编译到他的方法,所以发布后快,调式慢
13.泛型属性访问器,C#不支持;索引器不支持在类型上
// 第11章 事件
1.EventHandler 原型委托,System.EventArgs 参数原型
事件没有返回值,因为事件有好多个,但是FCL中ResolveEventHandler返回了Assembly类型的一个对象
2.线程安全用到的类 Thread.VolatileRead和Interlocked.CompareExchange
3.System.Reflection.EventInfo 获取event的信息
4.EventSet类跟系统中 System.ComponentModel.EventHandlerList对比
System.ComponentModel.EventHandlerList 1.使用的是链表2.没有提供安全线程
5.编写一个事件,参见EventDemo文件
// 1.设计公开事件
    // 1.1定义类型来容纳所有需要发送给事件通知接受者的附加信息
// 1.2定义事件成员
// 1.3定义负责引发事件的方法通知事件的登记对象
// 1.4定义方法将输入转化为期望事件


// 2.编译器如何实现 见 CompilerEvent
add_xx remove_xx


// 3.设计侦听事件类型 参见 Fax 类

// 4.显示实现事件 参见 EventSet
System.Threading.Monitor


// 第12章 泛型
1.泛型(generic)是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用,即"算法重用".
源代码保护,类型安全,更加清晰的代码,更佳的性能(不定义为Object) 参考类[OperationTimer]
2.CLR允许泛型创建泛型引用类型和泛型值类型,不允许创建泛型枚举类型.除此外还可以撞见泛型接口和泛型委托.
CLR也允许在引用类型、值类型或接口中定义泛型方法
3.FCL的泛型: 
集合:System.Collections.Generic List<T> ,  System.Collections.ObjectModel
线程安全:System.Collections.Concurrent
T成为 类型参数(Type Parameter)
4.System.Array 提供了大量静态泛型方法 Sort,BinarySearch
5.Wintellect的Power Collections库, 使CLR可以使用C++的标准模板库(Standard Template Library,STL)的部分集合类
BigList<T>,Bag<T>,OrderedBag<T>,Set<T>,OrderedSet<T>,Deque<T>,OrderedDictionary<TKey,TValue>,MultiDictionary<Tkey,TValue>,OrderedMultiDictionary<TKey,TValue>
http://www.wintellect.com/
6.智能感知(IntelliSense)
7.开放类型(open type)和封闭类型(Closed type)
参见 OpenAndClosedType
类型名称"`[数字]",数字代表类型的元数,也即所需参数的个数(Activator.CreateInstance)
泛型的静态对象,构造函数..泛型类型对象都会执行一遍
8.泛型类的同一性,参见 GenericTypeIsSame
9.代码爆炸(code explosion), 值类型每个类型生成一份本地代码,引用类型会生成一份代码
10.泛型接口  参考Triangle
没有泛型接口,每次试图使用非泛型接口(如IComparable)操纵一个值类型都会发生装箱操作
11.委托
public delegate TReturn CallMe<TReturn, TKey, TValue>(TKey key, TValue value);
编译器解释成:一个构造器,一个Invoke,一个BeginInvoke,一个EndInvoke
尽量使用系统中Action和Func
12.委托和接口的逆变和协变泛型类型实参
1.不变量(invariant),参数类型不可更改
2.逆变量(contravariant),可以从基类更改为派生类,用用in / ref(也可以)标记,只能作为输入位置; contravariance(逆变性)
3.协变量(covariant),可以从一个派生类更改为他的基类,用out标记,返回值类型;  covariance(协变性)
同一个T 不能同时使用 ref或out,便不允许可变.
不能通过编译:delegate void D<out T>(T t); delegate void D<T>(in T t);
可以编译:delegate void D<T>(ref T t); delegate void D<T>(out T t);delegate void D<in T>(T t);
13.泛型和其他成员
属性,索引器,事件,操作符方法,构造器,终结器(finalizer) 本身不能有类型参数
14.可验证性约束 参见 Triangle文件
where T:Comparable<T>,重写泛型方法时,不能改变约束
1.主要约束
可以有0个或1个主要约束,可以是一个引用类型,也可以是 struct,class (两个特殊的主要约束) [Sytem.Nullable<T>]
但不可以是 System.Object,System.Array,System.Delegate,System.MulticastDelegate,System.ValueType,System.Enum,System.Void
2.次要约束
可以有0个或多个次要约束
a)可以是口类型
b)另外一种参数类型约束(type parameter constraint),也叫 裸类型约束(naked type constraint)
public List<TBase> ConvertIList<T,TBase>(IList<T> list):where T:TBase{} 
3.构造器约束
0个或1个  where:new()  [new(),不能和struct 一起用,多余]
4.其他可验证问题
a)泛型类型变量的转型 int a=(int)(Object)T;
b)将一个泛型类型变量设为默认值 default(T)
c)将一个泛型类型变量与null比较 T==null , 如果T约束为 Struct 则报错
d)两个泛型比较 C<T>(T t1,T t1){if(t1==t2)} 会报错,因为不确定 T 是否有 == !=重载符
e)泛型类型变量作为操作数使用 T++ ,报错,因为T可能没有 ++ += < 等运算重载
// 第13章 接口
1.类和接口继承
接口"实现"了多继承(Multiple inheritance), 所有类都继承自Object
2.定义接口
接口对一组方法签名进行统一命名,接口还可以定义事件,无参属性,有参属性(索引器)
虽然CLR允许接口有静态方法,静态字段,常量和静态构造器,但CLS相容的接口不允许,C#也禁止
3.继承接口
方法 作用关键字 默认无(virtual和sealed),virtual,sealed(必须是override才可以用)
4.关于调用接口方法的更多探讨
接口引用类型,值类型的接口要装箱操作
5.隐式和显示接口方法实现(幕后发生的事情) [显示接口实现方法(Explicit Interface Method Implementation EIMI)]
接口和实现都有一套自己的引用方法地址;调用那个关键要看 地址的指向
显示接口private的,只有接口才可以访问,隐式相应的类访问


virtual 跟 override 访问性要看实际的类型,也即重写了父类的方法,只能在内部用base 调用
6.泛型接口
避免装箱,保护类型安全性
7.泛型和接口约束
接口是引用类型,值类型需要装箱
8.实现多个具有相同方法名和签名的接口
使用的时候必须转换成接口使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack_software

感谢打赏,我努力提供优质内容~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值