首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C#中struct与class,该怎么处理

2012-01-29 
C#中struct与class请问结构类型new 与不new 在内存中有什么区别吗?值类型是在栈里面分配空间,结构是值类型

C#中struct与class
请问结构类型new 与不new 在内存中有什么区别吗?值类型是在栈里面分配空间,结构是值类型如果new了后还是在栈里面分配空间吗?
下面是两份代码,第一份结构类型没有new直接给它里面的引用类型传引用。第二份是结构类型new了后在给它里面的引用类型传引用。从IL代码中我们可以看到是有区别的,因为对IL还不太熟悉,不知道它们内存怎么分配的,而且也不知道是在什么时候分配的,所以望高人指点。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace StructAndClass
{
  class Program
  {
  static void Main(string[] args)
  {

  ClassText classText;
  classText = new ClassText();
  classText.num = 5;
  classText.name = "Hello";

  StructText structText;
  structText.classText = classText;
   
  }
  }

  public class ClassText
  {
  public int num;
  public string name;
   
  }

  public struct StructText
  {
  public ClassText classText;
  public int n;
  }
}

Main函数的IL代码

.method private hidebysig static void Main(string[] args) cil managed
{
  .entrypoint
  // 代码大小 34 (0x22)
  .maxstack 2
  .locals init (class StructAndClass.ClassText V_0,
  valuetype StructAndClass.StructText V_1)
  IL_0000: nop
  IL_0001: newobj instance void StructAndClass.ClassText::.ctor()
  IL_0006: stloc.0
  IL_0007: ldloc.0
  IL_0008: ldc.i4.5
  IL_0009: stfld int32 StructAndClass.ClassText::num
  IL_000e: ldloc.0
  IL_000f: ldstr "Hello"
  IL_0014: stfld string StructAndClass.ClassText::name
  IL_0019: ldloca.s V_1
  IL_001b: ldloc.0
  IL_001c: stfld class StructAndClass.ClassText StructAndClass.StructText::classText
  IL_0021: ret
} // end of method Program::Main


第二份代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace StructAndClass
{
  class Program
  {
  static void Main(string[] args)
  {

  ClassText classText;
  classText = new ClassText();
  classText.num = 5;
  classText.name = "Hello";

  StructText structText = new StructText();
  structText.classText = classText;
  int x = structText.n;
   
  }
  }

  public class ClassText
  {
  public int num;
  public string name;
   
  }

  public struct StructText
  {
  public ClassText classText;
  public int n;
  }
}

Main函数的IL代码
.method private hidebysig static void Main(string[] args) cil managed
{
  .entrypoint
  // 代码大小 42 (0x2a)
  .maxstack 2
  .locals init (class StructAndClass.ClassText V_0,
  valuetype StructAndClass.StructText V_1)
  IL_0000: nop
  IL_0001: newobj instance void StructAndClass.ClassText::.ctor()
  IL_0006: stloc.0
  IL_0007: ldloc.0
  IL_0008: ldc.i4.5
  IL_0009: stfld int32 StructAndClass.ClassText::num
  IL_000e: ldloc.0
  IL_000f: ldstr "Hello"
  IL_0014: stfld string StructAndClass.ClassText::name
  IL_0019: ldloca.s V_1
  IL_001b: initobj StructAndClass.StructText


  IL_0021: ldloca.s V_1
  IL_0023: ldloc.0
  IL_0024: stfld class StructAndClass.ClassText StructAndClass.StructText::classText
  IL_0029: ret
} // end of method Program::Main


第二份IL代码明显多了两行,既然是初始化但也要给它分配空间呀,那是什么时候分的呢?

[解决办法]
调试的时候,看的汇编编码

Assembly code
        static void func()        {00000000  push        ebp  00000001  mov         ebp,esp//保存了esp到ebp中 00000003  push        edi  00000004  push        esi  00000005  push        ebx  00000006  sub         esp,3Ch //分配局部变量内存00000009  xor         eax,eax 0000000b  mov         dword ptr [ebp-44h],eax 0000000e  mov         dword ptr [ebp-40h],eax 00000011  mov         dword ptr [ebp-10h],eax 00000014  xor         eax,eax 00000016  mov         dword ptr [ebp-1Ch],eax 00000019  cmp         dword ptr ds:[00A89200h],0 00000020  je          00000027 00000022  call        76D66D87 00000027  xor         ebx,ebx 00000029  xor         edx,edx 0000002b  mov         dword ptr [ebp-48h],edx 0000002e  nop                          ClassText classText;            classText = new ClassText();0000002f  mov         ecx,0A89E94h 00000034  call        FD6B0A5C 00000039  mov         esi,eax 0000003b  mov         ecx,esi 0000003d  call        FD6CB0E0 00000042  mov         ebx,esi             classText.num = 5;00000044  mov         dword ptr [ebx+8],5             classText.name = "Hello";0000004b  mov         eax,dword ptr ds:[023C3098h] 00000051  lea         edx,[ebx+4] 00000054  call        76AB3F70             StructText structText = new StructText();00000059  lea         edi,[ebp-44h] 0000005c  pxor        xmm0,xmm0 00000060  movq        mmword ptr [edi],xmm0             structText.classText = classText;00000064  mov         dword ptr [ebp-44h],ebx             int x = structText.n;00000067  mov         eax,dword ptr [ebp-40h] 0000006a  mov         dword ptr [ebp-48h],eax         }0000006d  nop              0000006e  lea         esp,[ebp-0Ch]//恢复esp 00000071  pop         ebx  00000072  pop         esi  00000073  pop         edi  00000074  pop         ebp  00000075  ret 

热点排行