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 What is Rust? Safe, fast, and easy software development Unlike most programming languages, Rust doesn't make you choose between speed, safety, and ease of use. Find out how Rust delivers better code with fewer compromises, and a few downsides to consider before learning Rust. By Serdar Yegulalp Nov 20, 2024 11 mins Rust Programming Languages Software Development how-to Kotlin for Java developers: Classes and coroutines Kotlin was designed to bring more flexibility and flow to programming in the JVM. Here's an in-depth look at how Kotlin makes working with classes and objects easier and introduces coroutines to modernize concurrency. By Matthew Tyson Nov 20, 2024 9 mins Java Kotlin Programming Languages analysis Azure AI Foundry tools for changes in AI applications Microsoft’s launch of Azure AI Foundry at Ignite 2024 signals a welcome shift from chatbots to agents and to using AI for business process automation. By Simon Bisson Nov 20, 2024 7 mins Microsoft Azure Generative AI Development Tools news Microsoft unveils imaging APIs for Windows Copilot Runtime Generative AI-backed APIs will allow developers to build image super resolution, image segmentation, object erase, and OCR capabilities into Windows applications. By Paul Krill Nov 19, 2024 2 mins Generative AI APIs Development Libraries and Frameworks Resources Videos