怎样在网站上做友情链接,重庆最专业的房产网站建设,陕西网站建设网络公司,大概需要多少钱在.net运行时#xff0c;每一个类型在创建第一个实例#xff0c;或者静态成员被第一次访问#xff0c;或者被反射创建时#xff0c;就会创建一个与该类型关联的方法表#xff1a;
基本结构大概如下#xff1a;
--------------------------
| Method Table …在.net运行时每一个类型在创建第一个实例或者静态成员被第一次访问或者被反射创建时就会创建一个与该类型关联的方法表
基本结构大概如下
--------------------------
| Method Table |
--------------------------
| Virtual Method #1 ptr |
| Virtual Method #2 ptr |
| ... |
| Non-virtual Method ptr |
--------------------------
| Type Information |
| (Size, Base Type ptr, |
| ... other info) |
--------------------------其中重点分为两部分方法表与描述类型的元数据。
方法表中的每一项包含了方法的标识信息与指针ptr指针指向了方法体在内存中的实际地址。
方法表中的项又分为两类虚方法与实方法两者的区别体现在方法表的继承上。
举例子我创建了如下两个类他们存在继承关系
public class BaseClass
{public virtual void MethodA(){Console.WriteLine(BaseClass.MethodA);}public virtual void MethodB(){Console.WriteLine(BaseClass.MethodB);}
}public class DerivedClass : BaseClass
{public override void MethodB(){Console.WriteLine(DerivedClass.MethodB);}public virtual void MethodC(){Console.WriteLine(DerivedClass.MethodC);}
}两个类型的方法表如下
基类BaseClass的方法表
------------------------
| Method Table |
------------------------
| Virtual Method #1 | 函数指针指向 -- BaseClass.MethodA
| Virtual Method #2 | 函数指针指向 -- BaseClass.MethodB
------------------------子类DerivedClass的方法表
子类继承了基类的方法表项MethodA与MethodB
------------------------
| Method Table |
------------------------
| Virtual Method #1 | 未重写所以依旧指向 -- BaseClass.MethodA
| Virtual Method #2 | 重写了所以指向 -- DerivedClass.MethodB
| Virtual Method #3 | -- DerivedClass.MethodC
------------------------基于这种机制就实现了多态在创建实例时实例的“对象头”中包含了指向自身类型所对应的方法表的指针基于此找到方法表再根据方法标识找到对应的方法表项从而就自然而然找到了指向方法体的指针。
实例的“对象头”大概结构如下
----------------------
| 对象头 |
----------------------
| 类型指针 | -- 指向方法表的指针
| 同步锁信息 | -- 用于同步的信息
| 标记信息 | -- 垃圾回收标记信息
| ...其他元信息... |
----------------------
| 对象数据 | -- 实际存储对象数据的部分
----------------------当将“实例”作为参数传递时所传递的是“实例的引用”说人话就是传递指向上述结构中“对象头”部分起始位置的指针找到了“对象头”运行时自然也就能够知道该对象的类型信息了从而实现了高级的语言特性如多态性、垃圾回收等。调用虚方法、判断对象的实际类型等操作都依赖于这种引用机制使得对象在运行时能够灵活地适应不同的上下文。
抽象类
抽象类的方法表Method Table与普通类的方法表类似不过抽象类的方法表中可能包含抽象方法。抽象方法是一种只有方法签名而没有具体实现的方法需要在派生类中进行实现。
让我们通过一个简单的例子来理解抽象类的方法表。假设有如下的抽象类
public abstract class MyBaseClass
{public abstract void AbstractMethod();public void ConcreteMethod(){Console.WriteLine(Concrete method in MyBaseClass);}
}
对应的抽象类方法表可能类似于以下结构
------------------------
| Method Table |
------------------------
| Virtual Method #1 | -- MyBaseClass.AbstractMethod
| Virtual Method #2 | -- MyBaseClass.ConcreteMethod
------------------------在这个示例中
AbstractMethod 是一个抽象方法它在抽象类中只有方法签名而没有具体实现。ConcreteMethod 是一个普通的方法它有具体的实现。
抽象方法在方法表中会被表示为虚方法Virtual Method因为它们需要在派生类中进行具体的实现。派生类中实现的具体方法会在其自己的方法表中添加相应的条目。
当一个派生类继承了抽象类并实现了抽象方法时它的方法表可能会变成类似这样
------------------------
| Method Table |
------------------------
| Virtual Method #1 | -- DerivedClass.AbstractMethod (实现抽象方法)
| Virtual Method #2 | -- MyBaseClass.ConcreteMethod
------------------------这样抽象类的方法表中包含了抽象方法和具体方法的信息而派生类的方法表中则包含了实现的具体方法的信息。这种继承关系和方法表的组织方式使得多态性在抽象类和派生类中得以实现。
接口Interface 接口Interface在.NET中也有与之相关的方法表Method Table的概念不过与类的方法表有一些区别。接口中的方法表用于存储接口中定义的方法的签名而不包含具体的实现。
让我们通过一个简单的例子来理解接口的方法表。假设有如下的接口
public interface IMyInterface
{void InterfaceMethod();
}对应的接口方法表可能类似于以下结构
------------------------
| Method Table |
------------------------
| Virtual Method #1 | -- IMyInterface.InterfaceMethod
------------------------在这个示例中
InterfaceMethod 是接口中定义的方法它只有方法签名而没有具体实现。
当一个类实现了接口时它会实现接口中定义的方法并且在该类的方法表中会包含接口方法的实现。例如如果有如下的类
public class MyClass : IMyInterface
{public void InterfaceMethod(){Console.WriteLine(InterfaceMethod implementation in MyClass);}
}则 MyClass 的方法表可能会变成类似这样
------------------------
| Method Table |
------------------------
| Virtual Method #1 | -- MyClass.InterfaceMethod (实现接口方法)
------------------------这样接口的方法表记录了接口方法的签名而实现了接口的类的方法表包含了实际的方法实现。这种方式支持了类对多个接口的实现实现了接口隐式地引入了多态性允许通过接口引用调用具体实现的方法。