字符串如何存储在对象数组中?

时间:2012-06-16 22:44:23

标签: c# arrays string object

object[] objs = new object[]{"one","two","three"};

字符串是否存储在数组中作为字符串对象的引用

[@] - one
[@] - two
[@] - three

或是字符串对象存储在数组元素中吗?

[one][two][three]

感谢。

编辑:对不起,我的花哨图失败了。

4 个答案:

答案 0 :(得分:5)

字符串对象永远可以直接存储在数组中,也可以存储为任何其他变量。这是总是引用,即使在一个简单的情况下,例如:

string x = "foo";

此处x的值是引用,而不是对象。表达式值永远不是对象 - 它始终是引用,值类型值或指针。

答案 1 :(得分:4)

Jon Skeet很好地描述了实际的实现,但让我们考虑为什么CLR将字符串直接存储在数组中是荒谬的。

第一个原因是将字符串直接存储在数组中会损害性能。如果字符串直接存储在数组中,那么为了到达数组的元素1000,CLR必须遍历数组中所有字符串的字节,直到它到达元素1000,同时检查字符串边界。由于字符串和任何其他引用类型作为引用存储在数组中,因此查找数组的正确元素需要一个乘法,一个加法和一个指针(此处指针的概念位于实现级别,而不是程序员可见水平)。这会产生更好的性能。

字符串无法合理地直接存储在数组中的第二个原因是C# arrays of reference type are covariant。假设字符串直接存储在用

生成的数组中
string[] strings = new string[] {"one", "two", "three"};

然后,将其转换为对象数组,这是合法的

object[] objs = (object[])strings;

编译器应该如何生成考虑到这种可能性的代码?将对象数组作为参数的方法可以将一个字符串数组传递给它,因此CLR需要知道是否将数组索引为对象数组,字符串数组或其他类型的数组。不知何故,在运行时,每个数组都必须使用数组的类型声明进行标记,并且每个数组访问都必须检查类型声明,然后根据数组的类型以不同方式遍历数组。坚持引用更简单,它允许单个实现数组访问并提高引导性能。

答案 2 :(得分:2)

它们在内部存储为引用。存储该字符串的副本,并且在使用该字符串的任何位置,都存在对相同存储字符串的引用。 (这是字符串不可变的众多原因之一;否则,修改字符串的一个实例会在其出现的任何地方进行修改)

答案 3 :(得分:1)

所有基元类型都直接存储在数组中,但所有其他对象或引用类型都存储为内存引用。对于不限于字符串的所有对象都是如此。