在C#中,为什么字符串是一个类似值类型的引用类型?

在C#中,为什么字符串是一个类似值类型的引用类型?

字符串是引用类型,即使它具有值类型的大多数特征,例如不可变,并且需要=重载来比较文本,而不是确保它们引用同一个对象。

那么,为什么字符串不只是一个值类型呢?


RISEBY
浏览 807回答 3
3回答

呼唤远方

字符串不是值类型,因为它们可能很大,需要存储在堆中。值类型(到目前为止在CLR的所有实现中)都存储在堆栈上。堆栈分配字符串会破坏各种各样的东西:32位的堆栈只有1MB,64位的只有4MB,您必须将每个字符串装箱,造成复制代价,不能实习生字符串,内存的使用会急剧膨胀等等…。(编辑:增加了关于值类型存储是实现细节的说明,这导致了这样的情况:我们有一个类型,它的值义项不是从System.ValueType继承的。谢谢本)

胡子哥哥

在语言设计中,引用类型和值类型之间的区别基本上是一种性能权衡。引用类型在构造、销毁和垃圾收集方面有一些开销,因为它们是在堆上创建的。另一方面,值类型在方法调用上有开销(如果数据大小大于指针),因为整个对象被复制,而不仅仅是指针。因为字符串可以(而且通常是)比指针的大小大得多,所以它们被设计为引用类型。此外,正如Servy所指出的,值类型的大小必须在编译时知道,而字符串的情况并不总是这样。易变性问题是一个单独的问题。引用类型和值类型都可以是可变的或不可变的。但是,值类型通常是不可变的,因为可变值类型的语义可能会混淆。引用类型通常是可变的,但如果有意义,则可以设计为不可变。字符串被定义为不可变,因为它使某些优化成为可能。例如,如果同一个字符串文本在同一个程序中多次发生(这是非常常见的),编译器可以重用同一个对象。那么,为什么要重载“=”来按文本比较字符串呢?因为它是最有用的语义。如果两个字符串在文本上相等,则由于优化,它们可能是也可能不是相同的对象引用。因此,比较参考文献是非常无用的,而比较文本几乎总是你想要的。更广泛地说,Strings有所谓的价值语义..这是一个比值类型更普遍的概念,它是一个特定于C的实现细节。值类型具有值语义,但引用类型也可能具有值语义。当类型具有值语义时,您无法真正判断底层实现是引用类型还是值类型,因此可以考虑实现细节。
打开App,查看更多内容
随时随地看视频慕课网APP