结构体数组 - 数组元素是引用类型还是值类型?

3
C#如何处理结构体数组 - 我需要像处理类对象数组一样分配每个数组元素吗?
例如:
public struct RGBA { public byte red, green, blue, alpha; }

public RGBA [] colorBuffer = new RGBA [1024*1024];

现在,colorBuffer是一个指向RGBA对象的指针数组,我需要像这样分配它们吗:
for (int i = 0; i < colorBuffer.Length; i++)
    colorBuffer [i] = new RGBA ();

或者colorBuffer指向一个大小为4 MB的内存块,其中包含1 MB的RGBA结构体?

1
我曾经考虑过这个问题,但最终决定还是向您请教。没必要浪费您的时间回答您不想回答的问题。 ;) - Razzupaltuff
不要使用结构体数组,你知道什么是装箱/拆箱吗?请使用List<T>。 - sll
@sll,你不知道什么是装箱/拆箱。在强类型数组中不会存在装箱/拆箱(如问题所述)! - Simon MᶜKenzie
4个回答

8
colorBuffer变量的值将是对数组对象的引用。该数组对象本身将是一个单个对象,大小为4MB(4个字节*1024*1024)。该数组是引用类型,但每个元素都是值类型。元素的值是RGBA值-而不是指针。
每个元素会自动初始化为default(RGBA),因此您不需要执行自己的初始化。
如果您这样做:
RGBA[] other = colorBuffer;

这只是复制引用——两个变量现在都指向同一个数组。


谢谢你的见解。这让我想到了下一个问题:我有一个包含结构体的常量数组,而且数组中的结构体需要被初始化为不同的值。我找到的唯一方法是为数组中的每个结构体分配内存来进行初始化。 - Razzupaltuff
@karx11erx:实际上,不存在所谓的“const数组”-但如果你的意思是你有一个静态只读变量,我建议你编写一个方法来创建数组...这样更容易管理。LINQ 也可能适合你。 - Jon Skeet
其实我只是试图从C++中移植一个简单的查找表...顺便说一下,是的,4 MB内存,每个元素1 MB。 - Razzupaltuff

1
在这种情况下,数组元素是值类型。它们不需要使用new创建。例如,以下代码将编译并执行良好:
void Main()
{
    var colorBuffer = new RGBA [10];
    for (int i = 0; i < colorBuffer.Length; i++)
    {
        colorBuffer[i].red = (byte)i;
        Console.WriteLine(colorBuffer[i].red);
    }
}

struct RGBA { public byte red, green, blue, alpha; }

1

结构体始终是值类型。如果您创建了1024 * 1024个项目的数组,则所需的内存为(1024 * 1024)*(1 + 1 + 1 + 1)+ 数组的一些开销。


1
在C#中,数组是引用类型,尽管它的基础类型可能是值类型。

1
你的标题说的是这个。“结构体数组 - 数组元素是引用类型还是值类型?” 这不也是一个问题吗? - Jethro
你说“数组是引用类型”,但我问的是“数组元素”。这有很大的区别,而且我确保在问题标题中表达得清楚明白。 - Razzupaltuff
@karx11erx,是的,没错。有时候我会有点冲动。特别是在Skeet先生醒着的时候。顺便说一下,如果你有机会,可以阅读《深入理解C#》,它很好地介绍了引用类型和值类型。必须对这位大神表示敬意!;) - Jethro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接