四、共享程序集与强命名程序集
CLR #程序集
CLR via C#漫游者指南(四):共享程序集与强命名程序集
第四章《类型基础》介绍了CLR(公共语言运行时)中的类型系统,包括类型的继承、命名空间、程序集关系,以及运行时对象的内存管理。以下是本章的详细总结,并配以代码示例和图解说明:
1. 所有类型都派生自 System.Object
CLR 要求所有类型最终都继承自 System.Object,这意味着每个类型都至少具备 System.Object 的基本方法,如 ToString()、GetHashCode()、Equals() 等。
代码示例
class Employee // 隐式继承 System.Object
{
}
class EmployeeExplicit : System.Object // 显式继承 System.Object
{
}
System.Object 提供的方法:
| 方法 | 说明 |
|---|---|
Equals() |
判断两个对象是否相等 |
GetHashCode() |
返回对象的哈希值 |
ToString() |
返回对象的字符串表示 |
GetType() |
返回对象的运行时类型 |
2. 类型转换(Casting)
隐式转换
子类对象可以隐式转换为基类对象,无需额外语法:
Employee e = new Manager(); // Manager 是 Employee 的子类
显式转换
基类对象转换为子类对象时,必须使用 显式转换(可能会失败):
Employee e = new Employee();
Manager m = (Manager)e; // 运行时可能会抛出 InvalidCastException
new操作符
没有和new操作符对应的的delete操作符,没有办法显示释放为对象分配的内存。CLR采用垃圾回收机制自动释放对象内存。
is 和 as 关键字
is:用于检查对象是否为特定类型,返回true或false。as:尝试转换类型,如果失败,则返回null,不会抛出异常。
//CLR检查两次对象类型
object o = new Employee();
if (o is Employee) {
Employee e = (Employee)o;
}
//CLR仅需校验一次对象类型,更优
Employee e2 = o as Employee;
if (e2 != null) {
// 转换成功
}
3. 命名空间和程序集
命名空间用于组织代码,避免名称冲突。对于编译器,命名空间的作用就是为类型名称附加以句点分割的符号,使命名更长,更可能具有唯一性。例如:
namespace Company.Department
{
class Employee { }
}
程序集(Assembly)是CLR管理代码的基本单位,类型可以分布在多个程序集。
示例:
using System.IO;
using System.Text;
FileStream fs = new FileStream("test.txt", FileMode.Open);
StringBuilder sb = new StringBuilder();
上面的 using 指令允许在代码中使用简短类型名称,而不需要全限定名,如 System.IO.FileStream。
4. 运行时内存管理
运行时对象关系
CLR 维护堆(Heap)和栈(Stack):
- 栈(Stack):存储方法调用时的局部变量和参数,速度快。
- 堆(Heap):存储引用类型对象,动态分配,需垃圾回收。
代码示例
void M1() {
string name = "Joe";
M2(name);
}
void M2(string s) {
int length = s.Length;
}
执行流程
M1方法被调用时,name变量分配在 栈 上。M1调用M2(name),参数name被压入 栈。M2方法的局部变量length也存储在 栈。- 当
M2返回时,栈会释放length变量。
图示:
5. 继承和方法调用
CLR 维护 类型对象(Type Object),其中包含类型信息、方法表等。对象存储在 堆(Heap),并指向其对应的类型对象。
同步块索引(Sync Block Index)是什么?
在 CLR(公共语言运行时) 的 托管堆 中,每个对象都有两个隐藏的头部字段:
- 类型对象指针(Type Object Pointer):指向该对象的类型元数据。
- 同步块索引(Sync Block Index):用于支持 线程同步(Synchronization) 机制。
同步块索引是 对象头(Object Header) 的一部分,它存储在 对象的内存块之前,用于管理 锁定(Locking)、哈希码(HashCode)、垃圾回收(GC)标记 等信息。
代码示例
class Employee {
public virtual string GetReport() {
return "Employee Report";
}
}
class Manager : Employee {
public override string GetReport() {
return "Manager Report";
}
}
Employee e = new Manager();
Console.WriteLine(e.GetReport()); // 输出 "Manager Report"
执行流程
- 运行时,
e.GetReport()解析e的类型,发现其实际类型为Manager,调用Manager.GetReport()方法。
6. 方法表(Method Table)
每个类型在 CLR 中都有 方法表(Method Table),存储其方法指针:
- 非虚方法(Non-virtual method):直接调用目标方法。
- 虚方法(Virtual method):通过 方法表 查找实际类型的方法并执行。
方法调用示例
class Employee {
public virtual void Work() { Console.WriteLine("Employee working"); }
}
class Manager : Employee {
public override void Work() { Console.WriteLine("Manager working"); }
}
Employee e = new Manager();
e.Work(); // 调用 Manager.Work()
CLR 运行时会通过 vtable(虚方法表)查找
Manager.Work()方法,并调用它。
7. 类型对象(Type Object)
在 CLR 内部,所有对象都包含一个 类型对象指针,用于指向其类型信息。
对象存储示意图
当调用 e.Work() 时:
- 解析
e的类型对象。 - 通过
方法表查找Work()方法的实际实现(Manager)。 - 调用
Manager.Work()。
总结
本章介绍了CLR的 类型系统,包括:
-
所有类型最终继承
System.Object,并提供ToString()、GetType()等基本方法。 -
类型转换(Casting):
- 隐式转换(安全)
- 显式转换(可能失败)
is和as关键字 进行安全转换
-
命名空间和程序集 组织代码,避免命名冲突。
-
运行时内存管理:
- 栈(Stack) 存储局部变量,自动回收。
- 堆(Heap) 存储对象,垃圾回收管理。
-
方法调用:
- 非虚方法 直接调用。
- 虚方法 通过 方法表(Method Table) 查找实际实现。
-
CLR 内部对象存储:
- 类型对象(Type Object) 存储方法表、静态字段等。
- 对象包含类型对象指针,指向其类型信息。
作者:世纪末的魔术师
出处:https://www.cnblogs.com/Firepad-magic/
Unity最受欢迎插件推荐:点击查看
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号