Resolved Value types and reference types

Matthieu

Member
Joined
Aug 15, 2020
Messages
23
Programming Experience
Beginner
Hi everyone,

First question here...

If I'm correct, String is a reference datatype, right?
See my code below:

C#:
            String nameOne = "Matthew";
            String nameTwo = nameOne;
            nameOne = "Andrew";

In the end, I should expect both nameOne and nameTwo to be Andrew, but that's not the case.
nameTwo Stays Matthew. Can we conclude that String is special case and however it's a reference type, it behaves like a value type?

Thanks!
 
C#:
Button one = new Button();
Button two = one;
one = new Button();
Would you expect two to reference the same button as one here? Why? A new object has been assigned to just one of the variables.

With reference types you can refer to same object with two variables. After your line 2 check if these objects are equal (they are). So with both variables you can change the objects, for example after my line 2 I could change the Text property and could see that change from the other variable.

What is special with strings is that they are immutable, that means a string object can not change. That was not what your code did anyway, it created and assigned a new object to one variable.
 
You are confusing objects with their properties. Consider this type:
C#:
public class Person
{
    public string Name { get; set; }
}
Let's try the equivalent of your code on that type:
C#:
Person personOne = new Person {Name = "Matthew"};
Person personTwo = personOne;
personOne = new Person {Name = "Andrew"};
What should you expect there? A new object is created and personOne refers to it. Next, perosnTwo refers to that same object. Finally, another new object is created and personOne refers to that. Why should that last line have any effect on personTwo? Consider this real-world example. You hire someone named Matthew to clean your house. Some time after, you get Matthew to start cleaning your pool too. Some time after that, you get someone named Andrew to clean your house. What's the name of the person who cleans your pool? Matthew, right? Why are you expecting programming objects to work in some magic fashion that the real-world objects they're based on do not?

The reason that I think you are confused is that you are mixing that situation up with the following:
C#:
Person personOne = new Person {Name = "Matthew"};
Person personTwo = personOne;
personOne.Name = "Andrew";
In this case, there is only one Person object. After the second line, both personOne and personTwo refer to that object. In this case, instead of the last line assigning a new object to personOne, the code makes a change to the object that personOne already refers to. Because that is the same object that personTwo refers to, you will see that change reflected in the personTwo variable. Using my real-world example, this is like Matthew changing his name to Andrew after he starts cleaning your pool. There's only one person so any change to that person will be reflected whether you talk to the person cleaning your house or the person cleaning your pool.

Classes, i.e. reference types, are pretty easy to understand because they behave just like real-world objects, which is the whole point of object-oriented programming.
 
Can we conclude that String is special case and however it's a reference type, it behaves like a value type?
It can appear that way to begin with but String behaves every bit like a reference type. There are two differences between String and other reference types.

Firstly, as JohnH says, String objects are immutable, meaning that they cannot be altered once created. This is not unique among reference types though. A Font object cannot be changed once created either, and I would imagine that there are others.

Secondly, String is the only reference type that can be represented literally. In your original code, you were using literal Strings and that probably threw you because you didn't realise that a literal creates a new object. That's why the examples we've used since that use the new keyword to create new objects are equivalent.
 
C#:
Button one = new Button();
Button two = one;
one = new Button();
Would you expect two to reference the same button as one here? Why? A new object has been assigned to just one of the variables.

With reference types you can refer to same object with two variables. After your line 2 check if these objects are equal (they are). So with both variables you can change the objects, for example after my line 2 I could change the Text property and could see that change from the other variable.

What is special with strings is that they are immutable, that means a string object can not change. That was not what your code did anyway, it created and assigned a new object to one variable.

Thanks for your answer. I understand that within your code until line 2, variable one and two refer to the same button. After line 3 they are not the same anymore because you assign a new button to one. So actually it's the same as the code below, correct?:

C#:
            int[] x = { 10 };
            int[] y = x;
            y = new int[5];
Variable x and variable y refer to the same Array, but after line 3 they are different because you assing a new Array to variable y?
 
That is correct, and is the same case with your code and the strings, each string literal is a new instance.
 
Why would that be?

I think i'm starting to understand it. Based on the code below I got confused.

C#:
            int[] x = { 10 };
            int[] y = x;
            y[0] = 20;

Both arrays are still the same after line 3, but that's something different than changing a string with a literal.
 
I think i'm starting to understand it. Based on the code below I got confused.

C#:
            int[] x = { 10 };
            int[] y = x;
            y[0] = 20;

Both arrays are still the same after line 3, but that's something different than changing a string with a literal.
Yes, that is different. On line 3 you are changing one item in the array (similar to changing a property of an object), you are not assigning a new array to the y variable.
 
Back
Top Bottom