什么样的内存语义控制c#中的数组分配?
给定以下内容:字节[]sData和声明为专用字节[]的函数构造\u命令() 如果我随后将construct_command()的结果分配给sData什么样的内存语义控制c#中的数组分配?,c#,.net,C#,.net,给定以下内容:字节[]sData和声明为专用字节[]的函数构造\u命令() 如果我随后将construct_command()的结果分配给sData sData是否只指向从函数返回的内容,或者是否会在内存中为sData分配一些空间,并将函数结果的内容复制到其中?sData将指向从函数返回的内容。C#中的数组是引用类型,这意味着从另一个数组分配一个数组只是复制引用,而不是分配新数据。假设sData是一个局部变量,它将存在于堆栈中,并将引用该方法返回的数组。该方法不返回数组本身的内容,而是返回对数组
sData是否只指向从函数返回的内容,或者是否会在内存中为sData分配一些空间,并将函数结果的内容复制到其中?sData将指向从函数返回的内容。C#中的数组是引用类型,这意味着从另一个数组分配一个数组只是复制引用,而不是分配新数据。假设sData是一个局部变量,它将存在于堆栈中,并将引用该方法返回的数组。该方法不返回数组本身的内容,而是返回对数组的引用
在.net中,数组是第一类对象,所有数组类型变量实际上都是引用。赋值将简单地分配sData以引用construct_命令返回的实例。不会复制数据 一般来说,CLR将世界分为两种类型
- 值类型:这是从System.ValueType派生的任何内容。这些类型的值之间的赋值是按值进行的,基本上会导致位置之间的值的副本
- 引用类型:任何其他类型。这些类型的值之间的赋值只会导致位置引用内存中的不同对象。不会复制值
数组是CLR中的引用类型,因此不会导致基础值的复制
sData
将指向construct\u命令返回的数组
数组是引用类型,因此只复制引用。没有内容操作。数组是引用类型,这意味着实际数组在堆上实例化(可能是通过construct_command()),函数返回对数组的引用,并存储在(局部变量)sData中
因此,这实际上不是关于内存语义(返回值可以为null),而是关于引用类型的复制语义。情况完全相同,例如:
StreamReader reader = System.IO.File.OpenText(filename);
更直截了当地说:你根本无法在.Net中传递数组,你只能传递、复制和分配对数组的引用。虽然Rui的答案总体上是正确的,但我确实认为其中一部分是错误的。从堆栈内存中分配一个数组,然后通过引用访问它是没有意义的(非常不一致)。如果这是真的,那么底层内存可以从传递引用的任何方法下面释放出来 我相信亨克·霍尔特曼(Henk Holterman)的描述是正确的,他非常直接、毫不含糊地说:
数组是引用类型,这意味着实际数组是 在堆上实例化 感谢亨克的评论;我认为这是一个关键的部分,否则就会被公认的答案遗漏(并与之相矛盾)
(我本来会回复一条评论,但我没有足够的分数来回复,我认为重要的是要指出接受的答案有这个问题,我需要在这里添加一条新评论。)也许管理员可以删除对“局部变量,它将存在于堆栈中”的引用从答案来看。这是否意味着在包含局部变量(sData)的方法返回之前存在内容被破坏的危险?否,因为垃圾收集器将知道数组仍然被引用。