Explore value types and reference types in .Net and learn how and where they are stored Types in Microsoft .Net can be either value type or reference type. While value types are stored generally in the stack, reference types are stored in the managed heap. A value type derives from System.ValueType and contains the data inside its own memory allocation. In other words, variables or objects or value types have their own copy of the data. A reference type, meanwhile, extends System.Object and points to a location in the memory that contains the actual data. You can imagine a reference type similar to a pointer that is implicitly dereferenced when you access them. The built-in reference types supported by C# include: object, string, and dynamic. All fundamental data types, Boolean, Date, structs, and enums are examples of value types. Examples of reference types include: strings, arrays, objects of classes, etc. To create reference types in C#, you can take advantage of these keywords: class, interface and delegate. Note that unlike a reference type, you cannot derive from a value type, nor can you assign a null value directly to a value type. You can assign a null value to a value type only by taking advantage of nullable types — a feature added to the newer versions of .Net Framework. When a value type is copied to another, the value is copied. Hence, you can manipulate the values in them independent of the other — a change in one doesn’t affect the other. On the contrary, when you copy a reference type to another, the reference is copied. If you change one of them, the other is also affected. As an example, if one of the reference is set to null, the other also becomes null. Storage locations The CLR stores objects in three types of storage locations — the registers, the stack or the managed heap. While the short-lived objects are stored inside registers or stack, the long-lived objects are stored in the heap. As I mentioned earlier, value types are generally stored in the stack. It’s a common misconception that value types are always stored in the stack. I would rather say that value types can be stored in the stack when the variable is either a temporary variable or is a local variable and the JIT compiler decides not to enregister the value. In essence, the actual location of a value type depends on the implementation of the JIT compiler. Note that a value type can be stored in a stack frame, in the CPU register or even in the heap memory if the value type is contained inside an object, i.e., if it is a part of a reference type. On the contrary, reference types are stored in the GC heap. The reference is stored in a stack while the object is allocated in the heap. Instances or references of a value type are stored in the stack, the register or in the heap depending on whether the life time of the instance or the reference is short lived or a long lived. A value type can reside on the stack if they are local variables and in the managed heap if they are fields of a class, i.e., they belong to or are a part of a reference type. Passing by value and passing by reference The following code listing illustrates how you can pass a variable to a method by value. static void Increment(int i) { i = i + 1; } static void Main() { int x = 1; Increment(x); Console.WriteLine("The value of x is: " +x); Console.Read(); } Note that you can pass a value type as a reference to a method by using the ref keyword. The following code listing illustrates this. static void Increment(ref int i) { i = i + 1; } static void Main() { int x = 1; Increment(ref x); Console.WriteLine("The value of x is: " +x); Console.Read(); } When the above code is executed, the message “The value of x is: 2” will be displayed in the console. Boxing and unboxing The conversion of a value type to a reference type is known as boxing. Unboxing is just the opposite – it is defined as the process of conversion of a reference type to a value type. The following code snippet illustrates boxing and unboxing in C#. int i = 100; Object obj = i; //Boxing i = (int) obj; //Unboxing Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos