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.