internal class Program { static void Main(string[] args) { Chinese chinese = new Chinese(); int num = chinese.b; //b 字段无法访问,编译报错 Console.WriteLine(num); } } public class Person { public int a = 10; private int b = 11; } public class Chinese : Person { public int c = 12; }根据 C# 的类继承原则,上面的 chinese.b 写法肯定是无法被编译的,因为它属于父类的 私有字段,既然无法被访问,那这个 private b 到底去了哪里呢?要想找到答案,只能先从 chinese 实例处的汇编代码看起,看看有没有什么意外收获。
07FD6176 mov ecx,87205C4h 07FD617B call CORINFO_HELP_NEWSFAST (06E30C0h)这里的 87205C4h 就是 Chinese 类型的 MT,然后通过 CLR 下的 CORINFO_HELP_NEWSFAST 处的方法进行实例化。
07FD6180 mov dword ptr [ebp-40h],eax 07FD6183 mov ecx,dword ptr [ebp-40h] 07FD6186 call CLRStub[MethodDescPrestub]@7e34871e07fd5d20 (07FD5D20h) 07FD618B mov eax,dword ptr [ebp-40h]这里的 eax 是 CORINFO_HELP_NEWSFAST 初始化方法的返回值,可以在 ecx,dword ptr [ebp-40h] 处下一个断点,观察它的内存布局。
static void Main(string[] args) { unsafe { Chinese chinese = new Chinese(); fixed (int* ch = &chinese.a) { int b = *(ch + 1); Console.WriteLine($"b={b}"); } } } }
哈哈,是不是挺有意思。