在C#中指定新的结构来阵列时会发生什么? [英] What happens when assign new struct to array in C#?

查看:195
本文介绍了在C#中指定新的结构来阵列时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个C#结构:

struct Foo{
    int mA;
    public int A {get {return mA;}}
    int mB;
    public int B {get {return mB;}}

    public Foo(int a, int b)
    {
        mA = a;
        mB = b;
    }
}



然后我创建和Foo的数组:

And then I create and array of Foo's:

Foo[] foos = new Foo[10];



我这样做的时候会发生什么?

What happens when I do this?

foos[1] = new Foo(20, 10);

如果美孚是一个类时,富[]将举行一个指向堆Foo对象和该指针将被更改为新的Foo对象(被抛在回收旧)。

If Foo was a class, the Foo[] would hold a pointer to a Foo object on the heap, and that pointer would be changed to the new Foo object (the old one being left for recycling).

不过,由于结构是值类型,将在新的Foo(20,10)只是身体上覆盖先前由FOOS持有相同的内存位置[1]?

But since structs are value types, would the new Foo(20, 10) just physically overwrite the same memory location previously held by foos[1]?

推荐答案

在实践中有关阵列插槽相关联的内存由值填充。鉴于你的代码的一个小例子显示了下去。请参阅评论直列。这是一个发布版本。

In practice the memory associated with the relevant array slot is populated by the values. Given your code a small example shows what goes on. Please see comments inline. This is for a release build.

static void Main(string[] args)
{
    Foo[] foos = new Foo[10];
    foos[1] = new Foo(127, 255);
    Console.ReadLine();
}



以上JIT编译为代码如下

The code above is JIT compiled as follows

// Method setup
00280050 55              push    ebp
00280051 8bec            mov     ebp,esp
00280053 56              push    esi

// Create instance of Foo[]
00280054 b98a141d00      mov     ecx,1D148Ah
00280059 ba0a000000      mov     edx,0Ah
0028005e e8b121f4ff      call    CORINFO_HELP_NEWARR_1_VC (001c2214)
00280063 8bd0            mov     edx,eax

// Array range check 
00280065 837a0401        cmp     dword ptr [edx+4],1
00280069 7624            jbe     

// Assign foos[1] = new Foo(127, 255)  
0028006b 8d4210          lea     eax,[edx+10h]  <-- load location of foos[1] in eax
0028006e ba7f000000      mov     edx,7Fh        <-- load 127 in edx
00280073 beff000000      mov     esi,0FFh       <-- load 255 in esi
00280078 8910            mov     dword ptr [eax],edx    <-- move the value 127 to foos[1]
0028007a 897004          mov     dword ptr [eax+4],esi  <-- move the value 255 to foos[1] + offset

// This is just for the Console.ReadLine() part + rest of Main
0028007d e8d2436305      call    mscorlib_ni!System.Console.get_In() (058b4454)
00280082 8bc8            mov     ecx,eax
00280084 8b01            mov     eax,dword ptr [ecx]
00280086 8b402c          mov     eax,dword ptr [eax+2Ch]
00280089 ff501c          call    dword ptr [eax+1Ch]

// Epilog
0028008c 5e              pop     esi
0028008d 5d              pop     ebp
0028008e c3              ret

//Exception handling
0028008f e8f05e7f70      call    clr!JIT_RngChkFail (70a75f84)
00280094 cc              int     3

因此,在短期中,代码加载在寄存器中的常数,然后这些寄存器的值复制到与相关联的存储器阵列实例的有关部分。

So in short, the code loads the constants in registers and then copies values of these registers to the memory associated with the relevant part of the array instance.

这篇关于在C#中指定新的结构来阵列时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆