Why is a string a reference type?

Why is a string a reference type, although it is usually a primitive data type such as int, float or double.

+7
string c # primitive-types reference-type
source share
3 answers

Yikes, this answer was accepted, and then I changed it. I should probably include the original answer below, since this was accepted by the OP.

New answer

Update : here's what. string absolutely must behave like a reference type. The reasons for this have been affected by all the answers so far: the string type does not have a constant size, it makes no sense to copy the entire contents of the string from one method to another, string[] arrays should otherwise resize themselves - just to name a few.

But you can still define string as a struct that internally points to a char[] array or even a char* and int pointer by its length will make it immutable and voila !, you'd have a type that behaves like a reference type, but technically is a value type.

That would be pretty stupid, honestly. As Eric Lippert noted in several comments on other answers, defining a type of value like this is basically the same as defining a reference type. In almost every sense, it would be indistinguishable from a reference type defined in the same way.

So, the answer to the question "Why is string reference type?" there is, basically: "To do this type of value will be just silly." But if this is the only reason, then, in fact, the logical conclusion is that string can indeed be defined as a struct , as described above, and there would be no particular argument against this choice.

However, there are reasons why it is better to make a string a class than a struct , which are more than purely intelligent. Here is a couple I could think of:

To prevent boxing

If string was a value type, then every time you passed it to a method, waiting for an object , you would have to insert it into the box, which would create a new object that would inflate the heap and make senseless gas pressure. Since the strings are mostly everywhere, their appearance in boxing all the time will be a big problem.

For intuitive comparison comparisons

Yes, string can override Equals regardless of whether it is a reference type or a value type. But , if it was a value type, then ReferenceEquals("a", "a") will return false! . This is due to the fact that both arguments are obtained in the box, and the arguments in the box never have equal references (as far as I know).

So, although it is true that you can define a value type to act just like a reference type, since it consists of one field of the reference type, it still will not be exactly the same. Therefore, I support this as a more complete reason why string is a reference type: you can make it a value type, but it will only burden it with unnecessary flaws.


Original answer

This is a reference type because only references to it are passed.

If it were a value type, then every time you passed a line from one method to another, the whole line would be copied *.

Since this is a reference type, instead of string values ​​like "Hello world!" omitted - "Hello world!" this, by the way, is 12 characters, which means that it requires (at least) 24 bytes of storage - only links to these lines are transmitted. Walking around a link is much cheaper than passing each character in a string.

Also, this is really not an ordinary primitive data type. Who told you?

* Actually, this is not so true. If the string internally holds the char[] array, then as long as the array type is a reference type, the contents of the string will not actually be passed by value - there will only be a reference to the array. I still think this is basically the correct answer.

+11
source share

In addition to the reasons posted by Dan:

Value types are, by definition, those types that store their values ​​on their own, rather than referring to a value elsewhere. Therefore, value types are called value types, and reference types are called "reference types." So your question really is "why does a string refer to its contents, and not just its contents?"

This is because value types have the nice property that each instance of a given value type has the same size in memory.

So what? Why is this a good property? Well, suppose strings were types of values ​​that can be of any size and consider the following:

 string[] mystrings = new string[3]; 

What is the original contents of this three row array? For value types, there is no "zero" value, so the only reasonable thing is to create an array of three empty strings. How will it be laid out in memory? Think about it a bit. How do you do this?

Now suppose you say

 string[] mystrings = new string[3]; mystrings[1] = "hello"; 

Now we have "," hi "and" "in the array. Where does the" hi "go in memory? How big is the slot allocated for the mysteries [1]? The memory for the array and its elements must go somewhere.

This leaves the CLR with the following options:

  • resize the array every time you change one of its elements, copying the whole thing, which may be the size in megabytes
  • prohibit the creation of arrays of values ​​of types of unknown size
  • disable creation of value types of unknown size

The CLR team chose the latter. Creating strings in reference types means that you can efficiently create arrays.

+18
source share

A string is a reference type, not a value type. In many cases, you know the length of the string and the contents of the string; in such cases, it is easy to allocate memory for the string. but consider something like this.

 string s = Console.ReadLine(); 

it is not possible to find out the distribution details for "s" at compile time. The user enters values, and the entire row / row entered is stored in s. Thus, the strings are stored on the heap, so that the memory is redistributed to match the contents of the string s. A link to this line is stored on the stack.

To learn more read: .net zero by petzold

Read: garbage collection with Via C # CLR to post stack information.

Edit: Console.WriteLine (); in Console.ReadLine ();

+1
source share

All Articles