什么样的内存语义管理c#中的数组赋值?

时间:2009-08-12 14:38:52

标签: c# .net

给出以下内容: byte [] sData; 和声明为 private byte []的函数construct_command()

如果我要将 construct_command()的结果分配给 sData 将sData指向函数返回的内容,或者是否会为内存中的sData分配一些空间,并将函数结果的内容复制到其中?

7 个答案:

答案 0 :(得分:6)

赋值将简单地指定sData以引用construct_command返回的实例。不会复制数据。

一般来说,CLR将世界分为两类

  • 值类型:这是从System.ValueType派生的任何内容。这些类型的值之间的分配按值发生,并且基本上导致位置之间的值的副本
  • 参考类型:其他任何内容。这些类型的值之间的分配仅使位置引用存储器中的不同对象。不会复制值

数组是CLR中的引用类型,因此不会导致复制基础值。

答案 1 :(得分:3)

数组是引用类型,这意味着实际数组在堆上实例化(可能是由construct_command()),并且该函数返回对数组的引用,并存储在(局部变量)sData中。 / p>

所以这不是关于内存语义(返回值可能为null),而是关于引用类型的复制语义。这种情况完全相同,例如:

StreamReader reader = System.IO.File.OpenText(filename);

更坦率地说:你根本不能在.Net中传递一个数组,你只能传递,复制和分配对数组的引用。

答案 2 :(得分:2)

sData将指向函数返回的内容。 C#中的数组是引用类型,这意味着从另一个数组中分配一个数组只是复制引用而不是分配新数据。

答案 3 :(得分:2)

假设sData是一个局部变量,它将存在于堆栈中,它将引用到该方法返回的数组。该方法不返回数组本身的内容,而是返回对数组的引用。

在.net中,数组是第一类对象,所有数组类型变量实际上都是引用。

答案 4 :(得分:2)

Array是一种引用类型,因此只复制引用。没有内容操纵。

答案 5 :(得分:0)

sData会指向construct_command返回的数组。

答案 6 :(得分:0)

虽然Rui的答案总体上很好,但我认为其中一部分是不正确的。从堆栈存储器分配数组然后通过引用访问它是没有意义的(非常不一致)。如果这是真的,则可以从传递引用的任何方法下面释放底层内存。

我相信Henk Holterman在他非常直接且毫不含糊地说出来时正确地描述了它:

  

数组是引用类型,这意味着实际的数组是   在堆上实例化

感谢Henk的评论;我认为这是一个关键部分,否则会被接受的答案所遗漏(并且与之相矛盾)。

(我会回复评论,但我没有足够的回答,我认为重要的是要指出接受的答案对我来说有这个问题需要添加一个这里有新的评论。)也许管理员可以删除对#34;一个局部变量的引用,它将存在于堆栈中#34;从答案。