为什么字符串的引用类型? [英] Why is string a reference type?
问题描述
为什么字符串的引用类型,即使它是正常的基本数据类型如int,float或双。
哎呀,这个答案被录取了,然后我改变了它。我也许应该包括在底部的原来的答案,因为这就是由OP接受。
新答案
更新:这里的东西。 字符串
绝对需要的行为像的引用类型。造成这种情况的原因已经被到目前为止所有的答案谈到:在字符串
类型没有一个固定的大小,这是没有意义的,从复制一个字符串的全部内容一种方法到另一个,的String []
阵列否则将不得不调整themelves - 只是仅举几
但你仍然可以的确定的字符串
为结构
在内部指向的char []
阵列或者甚至一个的char *
指针和一个 INT
为它的长度,使之不可改变的,而瞧!的,你必须说的的行为像的引用类型,但为的技术上的值类型。
这似乎很愚蠢,真的。作为埃里克利珀已在少数的意见向其他的答案,限定值类型这样的指出的是基本相同定义引用类型。几乎在每一个意义上说,从引用类型定义相同的方式将是没有什么区别。
所以,这个问题的答案:为什么是字符串
引用类型?是,基本上是:为了使一个值类型也只是愚蠢的。但是,如果是这样的的只有的原因,那时候真的,合乎逻辑的结论是,字符串
实际上可能已经被定义为结构
如上所述,并会有反对这样的选择没有什么特别好的理由。
然而,是的原因,这是更好地使字符串
A 类
比一个结构
是比纯粹的智力了。这里有几个我能够想到的:
为prevent拳击
如果字符串
是值类型,那么每次它通过一些方法,时间等一个对象
将必须装箱,这将创建一个新的对象
,这将膨胀堆,造成无谓的GC pressure。由于串基本上处处的,让他们引起拳击所有的时间将是一个很大的问题。
直观相等比较
是字符串
可以覆盖等于
无论它是引用类型或值类型。但是如果它是一个值类型,那么的ReferenceEquals(A,A)
将返回的假的!这是因为这两个参数会得到盒装,盒装和参数的从不的有平等的引用(据我所知)。
因此,即使这是真的,你可以定义一个值类型采取行动的就像的有它由一个单一的引用类型字段的引用类型,它仍然不是的究竟的相同。所以,我保持这样的作为更完整的原因字符串
是引用类型:你可以把一个值类型,但是这只会不必要的弱点负担它。
原来的答案
这是一个引用类型,因为只有引用的它周围通过。
如果它是一个值类型,那么你每次从一个方法传递一个字符串到另一个整个字符串时间将复制*。
既然是引用类型,而不是像字符串值世界,你好!传递左右 - !世界,你好是12个字符,顺便说一句,这意味着它需要(至少)存储24个字节 - 唯一的引用的那些字符串传来传去。围绕一个引用传递要比通过每一个字符的字符串便宜多了。
此外,它的真正的不的一个正常的原始数据类型。谁告诉你的?
<子> *其实,这并不是真正的stricly。如果字符串内部召开了的char []
数组,那么只要数组类型是引用类型,字符串的内容实际上的不按值传递 - 只有参考阵列会。我仍然认为这基本上是正确的答案,但。
Why is string a reference type, even though it's normally primitive data type such as int, float, or double.
Yikes, this answer got accepted and then I changed it. I should probably include the original answer at the bottom since that's what was accepted by the OP.
New Answer
Update: Here's the thing. string
absolutely needs to behave like a reference type. The reasons for this have been touched on by all answers so far: the string
type does not have a constant size, it makes no sense to copy the entire contents of a string from one method to another, string[]
arrays would otherwise have to resize themelves -- just to name a few.
But you could still define string
as a struct
that internally points to a char[]
array or even a char*
pointer and an int
for its length, make it immutable, and voila!, you'd have a type that behaves like a reference type but is technically a value type.
This would seem quite silly, honestly. As Eric Lippert has pointed out in a few of the comments to other answers, defining a value type like this is basically the same as defining a reference type. In nearly every sense, it would be indistinguishable from a reference type defined the same way.
So the answer to the question "Why is string
a reference type?" is, basically: "To make it a value type would just be silly." But if that's the only reason, then really, the logical conclusion is that string
could actually have been defined as a struct
as described above and there would be no particularly good argument against that choice.
However, there are reasons that it's better to make string
a class
than a struct
that are more than purely intellectual. Here are a couple I was able to think of:
To prevent boxing
If string
were a value type, then every time you passed it to some method expecting an object
it would have to be boxed, which would create a new object
, which would bloat the heap and cause pointless GC pressure. Since strings are basically everywhere, having them cause boxing all the time would be a big problem.
For intuitive equality comparison
Yes, string
could override Equals
regardless of whether it's a reference type or value type. But if it were a value type, then ReferenceEquals("a", "a")
would return false! This is because both arguments would get boxed, and boxed arguments never have equal references (as far as I know).
So, even though it's true that you could define a value type to act just like a reference type by having it consist of a single reference type field, it would still not be exactly the same. So I maintain this as the more complete reason why string
is a reference type: you could make it a value type, but this would only burden it with unnecessary weaknesses.
Original Answer
It's a reference type because only references to it are passed around.
If it were a value type then every time you passed a string from one method to another the entire string would be copied*.
Since it is a reference type, instead of string values like "Hello world!" being passed around -- "Hello world!" is 12 characters, by the way, which means it requires (at least) 24 bytes of storage -- only references to those strings are passed around. Passing around a reference is much cheaper than passing every single character in a string.
Also, it's really not a normal primitive data type. Who told you that?
*Actually, this isn't stricly true. If the string internally held a char[]
array, then as long as the array type is a reference type, the contents of the string would actually not be passed by value -- only the reference to the array would be. I still think this is basically right answer, though.
这篇关于为什么字符串的引用类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!