Value types and reference types
A variable of a value type holds the value itself. A variable of a reference type holds a reference to an object stored elsewhere.
Assignment
Assigning a value type copies the value, so the two variables are independent. Assigning a reference type copies the reference, so both variables point at the same object.
int a = 5;int b = a; // copies the valueb = 10; // a is still 5 var p1 = new Person { Name = "Ada" };var p2 = p1; // copies the reference: the same objectp2.Name = "Grace";Console.WriteLine(p1.Name); // GraceMethod arguments
Arguments are passed by value: a value type is copied, and for a reference type the reference is copied. A method can change an object’s contents but not the caller’s variable. ref, out and in pass the variable itself. This is the struct trap in extension methodsExtension methods: custom types, value types and usingWhich types can be extended, how structs behave, and when an extension method is visible.Opens in a new tab.
null and storage
Reference types can be null. A value type cannot, unless it is nullable, as in int?. A value type lives where it is declared: on the stack as a local, inside the object as a field, inside the array as an element. The object a reference points to is on the heap.
Boxing
Converting a value type to object or to an interface wraps it in a heap object, which allocates and copies. GenericsGenerics at compile time and at runtimeGeneric code is type-checked by the compiler, and the types stay real at runtime.Opens in a new tab avoid it.
Where it matters
The kind decides whether a copy is independent, whether == compares references or contents, whether a variable can be null, and whether an assignment allocates. string is a reference type that behaves like a value, because it is immutable and == compares its contents. Structs and classes are compared in class versus structClass versus structA struct is a value type and a class is a reference type.Opens in a new tab.