question

Alice-2652 avatar image
0 Votes"
Alice-2652 asked YijingSun-MSFT answered

Assign value to one property change another property value

Need some clarification on the below please.
Also if you don't mind some C# low level explanation and/or books on the matter please.

Why after assigning value to secondDog.breed property (3rd line), both properties got the same value (firstDog.Breed and secondDog.Breed).

Seems like only secondDog that is supposed to display "Labrador", not firstDog !!


     static void Main(string[] args)
     {
         var firstDog = new Dog() { Breed = "Bulldog" };
         var secondDog = firstDog;

         secondDog.Breed = "Labrador";   // Magic happens here !!!

         Console.WriteLine(firstDog.Breed);      // Labrador (why ???)
         Console.WriteLine(secondDog.Breed);     // Labrador
     }
        
     class Dog
     {
         public string Breed { get; set; }
     }


Why on the below code I get different result than on the above code (Dog example)


 int num = 5;
 int numb = num;

 numb = 30;

 Console.WriteLine(num);    // 5  (Not 30 like in the above Dog example)
 Console.WriteLine(numb);   // 30
dotnet-csharpdotnet-aspnet-general
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

cooldadtx avatar image
1 Vote"
cooldadtx answered

That is the classic value type vs reference type. All types in .NET are either value or reference types.

Value types follow value semantics. That means that when you assign one variable to another (such as your ints above) then the runtime copies the value. Hence in memory you have 2 variables and they each have their own copy of the value. Changing one has no impact on the other. This is because value type values are stored on the call stack with the variable they are assigned to.

In .NET. In C# you can tell a value type because it listed as a struct when you look at the type declaration. All primitives other than string and object are value types in C# (e.g. int, double, bool).

Reference types follow reference semantics. That means that when you assign one variable to another you are actually copying the reference to the underlying object. Hence in memory you have 2 variables but they both reference (point to) the same underlying object. So if you change the state using one of the variables then the other variable will see those changes as well (because they are the same object).

In C# reference types are marked as classes. Besides string and object none of the C# primitives are reference types but most types in .NET are reference types.

This happens because reference types are allocated on the heap each time you call new. A reference to that instance is then assigned to whatever variable you give it to.

var firstDog = new Dog();  //1 instance allocated, reference assigned to variable
var secondDog = secondDog;  //Now both variables refer to that same instance in memory

var areEqual = firstDog == secondDog;  //Will always be true

secondDog= new Dog();  //1 instance allocated, reference assigned to variable
areEqual = firstDog == secondDog;  //Will always be false


When comparing 2 value types for equality they are equal if the values they contain are equal. Hence num == numb is true. For reference types equality is handled (unless overridden) by comparing the references stored in the variables. Hence 2 variables are equal only if they refer to the same object.

In general prefer value types for small values (generally less than 64 bytes) and those values that are atomic (e.g. lat/log or complex number). Use reference types for everything else.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered

classes are reference, but structs are value types (copied on assignment).


 public static void Main(string[] args)
 {
          var firstDog = new Dog() { Breed = "Bulldog" };
    
          var secondDog = firstDog;                       // copy struct
          secondDog.Breed = "Labrador";              // update copy
    
          Console.WriteLine(firstDog.Breed);          // Bulldog
          Console.WriteLine(secondDog.Breed);     // Labrador
 }
            
 struct Dog
 {
          public string Breed { get; set; }
 }


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

YijingSun-MSFT avatar image
0 Votes"
YijingSun-MSFT answered

Hi @Alice-2652 ,
Classes are reference.Assignment of reference variables After the assignment operation is completed, both variables point to the same memory address. So, secondDog.Breed = "Labrador" and the firstDog.Breed = "Labrador".

Best regards,
Yijing Sun


If the answer is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our  documentation  to enable e-mail notifications if you want to receive the related email notification for this thread.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.