【问题标题】:How are strings stored in an object array?字符串如何存储在对象数组中?
【发布时间】:2012-06-16 22:44:23
【问题描述】:
object[] objs = new object[]{"one","two","three"};

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

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

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

[one][two][three]

谢谢。

编辑:抱歉,我的精美图表惨遭失败。

【问题讨论】:

  • 感谢指正。我正在编辑。

标签: c# arrays string object


【解决方案1】:

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

string x = "foo";

这里x 的值是一个引用,而不是一个对象。没有表达式值永远是对象 - 它始终是引用、值类型值或指针。

【讨论】:

  • 要明确一点:objs 是对堆上数组的引用,而元素是对也在堆上的字符串对象的引用,对吧?
【解决方案2】:

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 需要知道是将数组作为对象数组、字符串数组还是其他类型的数组进行索引。不知何故,在运行时,每个数组都必须用数组的类型声明进行标记,并且每个数组访问都必须检查类型声明,然后根据数组的类型以不同的方式遍历数组。坚持使用引用要简单得多,它允许数组访问的单一实现并提高启动性能。

【讨论】:

  • 你现在有点不知所措,但我会留到以后。谢谢!
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多