I understand string is reference type.
string s;
Is "s" pointing a stack or heap object ?
Printable View
I understand string is reference type.
string s;
Is "s" pointing a stack or heap object ?
All reference types live on the heap. Only value types live on the stack, though value type will live on the heap if you box it (cast it to object).
You will be implicitly :
compiles to (in IL)Code:string s = "hello";
If you look in the docs it says thatCode:.locals init (
[0] string s)
L_0000: nop
L_0001: ldstr "hello"
L_0006: stloc.0
So "hello" is stored in the metadata of the assembly, but the ldstr instruction creates a reference to a string object (i.e. on the heap) from this metadata.Quote:
ldstr
Pushes a new object reference to a string literal stored in the metadata.
Darwen.
I have the question in same line
then why reference of string is not passed to any of my function
ie
code:
public static void swap(string s1, string s2)
{
// If Pass strings from main to this function i will get local copies of s1 and s2
//instead of their references
}
code:
Any help is appreciated
Thanks in advance.
if you want to pass a reference as paramater, you need to add the 'ref' modifier.
Code:public static void swap(ref string s1, ref string s2)
{
...
}
How do you know you're getting local copies ?Quote:
// If Pass strings from main to this function i will get local copies of s1 and s2
//instead of their references
Actually you're not getting local copies, you're getting references. The strings are passed by reference. Because System.String is a class which are always passed by reference in .NET - that's why they are called 'reference types'.
But System.String is peculiar in that it is an immutable class i.e. it exposes no methods which allow you to change the contents of the class once it's been created. Hence it behaves like a value type, but in fact is a reference type.
That's probably why you think you're getting a local copy - you aren't, you are just getting references to instances of string which you can't change.
Darwen.
So, what happens in s1 = s2 ?Code:string s1 = "first string";
string s2 = "second string";
s1 = s2;
- Is that the address of s2 copied to s1 (Shallow copy)?
- Copy the entire contents (deep copy) ?
- or What ?
They are references, so the reference is copied to s1;
Thank you BigEd781.
May I know what makes it immutable.
may be the keyword "sealed" which dont allow you to inherit the string class further ?
No, it is immutable simply because the class gives you no way to change its member data. Look at this class:
That class is immutable. You pass some data into the constructor, the data is set, and now there is no way that it can be changed by the outside world.Code:class Foo
{
public readonly int Id;
public readonly string Name;
public Foo( int id, string name )
{
Id = id;
Name = name;
}
}
Well, it could have non-const data within the class, but I think you get the point; the class does not expose a way for the outside world to change said data, and that data is guaranteed to not be changed during the lifetime of the object. The string class will have an internal char[] that contains the actual string data. Whenever you call a method that seems to change the string, you are actually getting a new (new String( data )) back in return.
An immutable class will simply not allow its state to be changed, period. This makes a class like that great for dealing with concurrency because you do not have to worry about intermediate states between writes and reads.
Thanks again.
So it's way clear now.
So every time, when a string provides an illusion to change it's data, it's actually creating a new string object internally. And the original data is unchanged.
After doing some research on this subject, I think it's an attempt to give a value type behavior to strings. Also as you told, it tries to provide const type behavior to strings, which is greatly helpful while using them in functions.
But I figure out one disadvantage:
Lets create an object to occupy 4 bytes say - A, B, C, D.
When I want another 'E', it is NOT expanding the current memory, but it simply forgets, and create a new memory in entirely new location.
So this is sort of an overhead.
(Let's don't jump into StringBuilder for now)
I believe there should be valid reasons, that are more critical comparing this overhead.
I think the reason to be to - Take the value type advantage. Am I right ?
If strings were mutable then every internal .NET function which returns a string would have to clone the string and return a copy. If you wrote a library, every place where you receive a user string and store it you'd have to clone it, every place you return a string to the user you'd have to clone it.
It'd become a giant source of bugs and issues.
The other thing is it's not possible to 'expand' a memory location as you suggest. If you want a 10 char string, you'd want .NET to allocate exactly 10 chars of space, otherwise you'd be wasting memory. So, what happens if you want to append a character? You have to get another memory location containing *11* chars of space, copy over the original 10 chars and append the new char. Essentially exactly what .NET does ;)
Of course, you could always hide this inside the string class, but as i said, it'd lead to a whole host of bugs and not give any performance benefits.