String是一种引用类型,尽管它具有值类型的大多数特征,例如不可变和重载==以比较文本,而不是确保它们引用同一个对象。
为什么字符串不只是一个值类型呢?
String是一种引用类型,尽管它具有值类型的大多数特征,例如不可变和重载==以比较文本,而不是确保它们引用同一个对象。
为什么字符串不只是一个值类型呢?
当前回答
如何知道字符串是引用类型?我不确定它是如何实施的。c#中的字符串是不可变的,所以你不必担心这个问题。
其他回答
字符串不是值类型,因为它们可能很大,需要存储在堆上。值类型(在CLR的所有实现中)存储在堆栈上。堆栈分配字符串会破坏各种各样的事情:32位的堆栈只有1MB, 64位的堆栈只有4MB,你必须装箱每个字符串,导致复制惩罚,你不能实习字符串,内存使用会膨胀,等等……
(编辑:增加了关于值类型存储是实现细节的说明,这导致了这种情况,即我们有一个具有值语义的类型没有从System.ValueType继承。由于本。)
不仅字符串是不可变的引用类型。 还有多类型转换委托。 这就是为什么写信是安全的
protected void OnMyEventHandler()
{
delegate handler = this.MyEventHandler;
if (null != handler)
{
handler(this, new EventArgs());
}
}
我认为字符串是不可变的,因为这是使用它们和分配内存的最安全的方法。 为什么它们不是值类型?以前的作者对堆栈大小等的看法是正确的。我还会添加,使字符串引用类型允许在程序中使用相同的常量字符串时节省程序集大小。如果你定义
string s1 = "my string";
//some code here
string s2 = "my string";
“my string”常量的两个实例很可能只在程序集中分配一次。
如果你想像一般引用类型一样管理字符串,把字符串放在一个新的StringBuilder(string s)中。或者使用MemoryStreams。
如果您要创建一个库,并希望在函数中传递一个巨大的字符串,则可以将参数定义为StringBuilder或Stream。
这是对一个老问题的迟来的回答,但所有其他的回答都忽略了一点,那就是。net直到2005年的。net 2.0才有泛型。
String是一种引用类型,而不是值类型,因为对于Microsoft来说,确保字符串能够以最有效的方式存储在非泛型集合(如System.Collections.ArrayList)中至关重要。
在非泛型集合中存储值类型需要对类型对象进行特殊的转换,这种转换称为装箱。当CLR装箱一个值类型时,它将该值包装在系统中。对象,并将其存储在托管堆上。
从集合中读取值需要反向操作,称为开箱操作。
装箱和拆箱都有不可忽略的成本:装箱需要额外的分配,拆箱需要类型检查。
一些答案错误地声称字符串永远不可能被实现为值类型,因为它的大小是可变的。实际上,将字符串实现为包含两个字段的固定长度数据结构是很容易的:字符串长度的整数和指向char数组的指针。你也可以在此基础上使用小字符串优化策略。
如果泛型从第一天就存在,我想将字符串作为值类型可能是一个更好的解决方案,具有更简单的语义,更好的内存使用和更好的缓存位置。只包含小字符串的List<string>可能是单个连续的内存块。
简单地说,任何具有一定大小的值都可以被视为值类型。
这主要是性能问题。
在编写代码时,让字符串的行为像值类型一样有帮助,但如果它是值类型,则会对性能造成巨大影响。
要深入了解,请参阅一篇关于.net框架中字符串的好文章。