Is string a value type or a reference type?
Asked Answered
P

8

50

Is string a value type or a reference type?

I just can't find a "good" explanation for this...

Precedency answered 1/7, 2009 at 13:30 Comment(3)
related #637432Floatable
The accepted answer "proves" it is a reference type. Unlike other reference types it does not throw the NullReferenceException when evaluated in the following: string s0 = null; Console.WriteLine(s0); string result = String.Concat(s0, "aaa"); Perhaps it just does not fit neatly into the acknowledged categories.Socorrosocotra
@Socorrosocotra it is not expected to throw that exception in those cases; the methods could choose to throw ArgumentNullException, but both methods explicitly say that they do not choose to do that; Console.WriteLine says: "If value is null, only the line terminator is written to the standard output stream."; String.Concat says "An Empty string is used in place of any null argument.". And that's perfectly fine. The only time we would typically expect NullReferenceException is things like s0.Length, which: indeed, throws thatVani
V
95
Console.WriteLine(typeof(string).IsClass); // true

It's a reference type.

It can't be a value-type, as value-types need a known size for the stack etc. As a reference-type, the size of the reference is known in advance, even if the size of the string isn't.

It behaves like you expect a value-type to behave because it is immutable; i.e. it doesn't* change once created. But there are lots of other immutable reference-types. Delegate instances, for example.

*=except for inside StringBuilder, but you never see it while it is doing this...

Vani answered 1/7, 2009 at 13:34 Comment(10)
+1. I really dislike the lower-case string "type." Looks like a value type, behaves like a reference type.Deweese
What has the case got to do with it? It is just an alias... object is reference-type, for example.Vani
StringBuilder uses a char[] internally, not a string.Remscheid
@Phong check again. Last time I looked, it honestly was a string - it then does unsafe mutates (allocating a new string and copying when needed). Have you checked? And if so: what .net version?Vani
@marc, saying it does change the existing string when inside of a stringbuilder is a bit for me... I realize it's only semantics, and it doesn't matter since the behavior is hidden inside of SB, but what if you append another string to the SB that is ten times bigger, and the existing SB is in a block of memory with stuff on both ends? In that case it clearly has to create a new block of memory somewhere else right? Although I am not 100% sure, I think it's safe to say it is NOT in the intern table.Cummine
@SMI the default value of a string is null, precisely because string is a reference type. It is incorrect to say that the default value of a string is "", because: it isn't.Vani
@Marc Gravell the underlying array is a char[ ] .Paulenepauletta
@MihailGeorgescu no, it isn't; sorry, but that is simply incorrect. The m_firstChar is used internally as a place holder to act as a char* pointer to the start of the data, but it does not contain a char[] (or a reference to a char[]). The object itself is the data. It is one of only 2 object types (the other being arrays) that are allocated by the runtime with variable length.Vani
@MarcGravell don't take my word sir , I am pretty sure you are alot more experienced than I am. I just checked StringBuilder's ToString() method.Paulenepauletta
@Mihail ah, I was talking primarily about string. Re StringBuilder: they actually rewrote that in 4.something; back in 2009 it was a naked string underneath, being mutated. The current implementation is much more complex with some kind of linked chain of parts, effectively.Vani
P
17

String is an immutable reference type.

See the blog post Immutable types: understand their benefits and use them on immutability.

Pupil answered 1/7, 2009 at 13:32 Comment(0)
S
13

String is a reference type.

Stephanstephana answered 1/7, 2009 at 13:31 Comment(0)
C
11

The fundamental "explanation" is based on "what" is actually stored in the memory location allocated when you "declare" the variable for the thing. If the actual value of the thing is stored in the memory location referred to by the variable name, then it is a value type.

   int x;  // memory allocated to hold Value of x, default value assigned of zero

If, otoh, the memory slot allocated when you "declare" the variable will hold only some other memory address where the actual value (or values) will be stored, then it is a reference type.

   MyClass x;  // Memory allocated to hold an address, 
               // default address of null (0) assigned.  
               // NO MEMORY ALLOCATED for x itself 

or, if declaration includes initialization,

   MyClass x = new MyClass();  
     // Now, Memory slot (call it Addr1) is allocated to hold address of x, 
     // more memory (call it Addr2) is allocated to hold a new MyClass object.
     // New MyClass object created, stored in memory Addr2 (on the Heap)
     // Address of new object (Addr2) is stored in Addr1

for a string, the string is created on the Heap, and it's address goes in the memory slot allocated for the variable, so it is a reference type.

Cummine answered 1/7, 2009 at 14:4 Comment(0)
B
6

String is an immutable reference type which has certain qualities that give it the occasional appearance of being a value type

Blimp answered 1/7, 2009 at 13:34 Comment(0)
J
4

The string type represents a sequence of zero or more Unicode characters. string is an alias for String in the .NET Framework.

Although string is a reference type, the equality operators (== and !=) are defined to compare the values of string objects, not references. This makes testing for string equality more intuitive. For example:

string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine((object)a == (object)b);

This displays "True" and then "False" because the content of the strings are equivalent, but a and b do not refer to the same string instance.

Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this. For example, when you write this code, the compiler actually creates a new string object to hold the new sequence of characters, and that new object is assigned to b. The string "h" is then eligible for garbage collection.

string b = "h";
b += "ello";
Jegger answered 1/6, 2015 at 12:31 Comment(0)
M
3

In many languages, there are two general types of things: those where a storage location of a defined type will actually hold an object of that type, and those where a storage location of a defined type will hold a reference to an object of that type which is stored elsewhere. There are also a number of types of semantics things may offer:

  1. Immutable value semantics: instances of a particular type have some characteristic ("the value") which forms the basis of identity. Two items whose value is equal may be used interchangeably, regardless of where they are stored. The value will be constant as long as the instance exists. A variable of such a type may have its value changed, but only by storing a different instance into the variable.
  2. Immutable reference semantics: generally similar to immutable value semantics, except that two instances which were created at different times will report themselves as being different instances.
  3. Mutable value semantics: instances of a particular type have some characteristic or collection of characteristics ("the values") which forms the basis of identity, but those characteristics may be changed without replacing the entire instance. Every instance is stored in precisely one variable or field; copying one variable or field to another copies all the values from one the first instance to the second, but the instances remain separate. Future changes to one instance will not affect the other.
  4. Mutable reference semantics: every instance is identical to itself, but to no other entity, and instances have one or more values which may be changed within existing instances. Any number of variables or fields may hold a reference to any instance. Copying one or field variable to another simply makes the second refer to the same instance as the first. Consequently, any change to the instance referred to by one of the variables will affect the instance referred to by the other (i.e. the same instance).

In some programming languages like C++, it is possible for both direct-stored and indirect-reference types to implement any of the above four types of semantics. In .net and C#, direct-stored types with exposed fields always implement #3, class types with exposed fields always implement #4, other value types may implement any of the above, and other reference types may implement #1, #2, or #4, but not #3, with an only-slightly-leaky abstraction. Strings implement #1.

Mauricio answered 10/12, 2011 at 21:14 Comment(0)
D
2

Maybe the article Strings in .NET and C# can help you. According to this article, string is a reference type.

Defamatory answered 1/7, 2009 at 13:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.