Value Types and Reference Types in C#

Value Types and Reference Types in C#

This post was originally published on the Productive C# blog in 2019.

Learn about the difference between value types and reference types in C#.?

Have you enjoyed this video?

Join our Modern C# Course (Free) and be the first to receive new videos and articles on C# and .NET.

Transcript of the video

In this video I am going to explain the difference between value types and reference types in C#. This is a very important thing to understand when you are new to the C# language. The best way for learning this is by example.

Let's start with this console application. I have defined a value type called Point. In order to define a vlue type, I use the struct keyword in C#. This type contains an X and a Y that represent a point in space. It has a constructor and there is a Tostring method that basically returns a string representation of Point.

The main program instantiate point1 then assign point1 to point 2 and then attempt to change X and Y of point2 and finally is printing point1 and point2. Let's have a look at what happen in memory when you execute this code. As you can see we are printing (1,1) and (2,2). So this means that point1 and point2 are actually holding different locations of the data. When I do an assignment, what really happens is that a copy of the memory that point1 represents is copied into an another location that point2 represents. This means that point1 and point2 are actually two locations in memory that are completely indipendent from each others. If you attempt to change any information inside point2 nothing happen on point1. They are two completely isolated locations.?

A value type holds the data withing his own memory allocation. When you do an assignment, a copy by value occurs and if you change that value nothing happen to the original value.

No alt text provided for this image

Let's see what happen when I change this struct to a class. The class keyword is how you define a refernece type in C#. The program code still compiles but the semantics is completely different. What happens at runtime is different.

Let's run this program and see what's happen. Now the result is (2,2) and (2,2). Interesting!

Reference types contains the memory address to an another memory location that holds the data. So point1 and point2 are just pointers to the same memory location. When you do point1 = point2 and those types are ference types, you are actually copying one pointer to an another. Then later on, when you actually change X and Y using point2 you are also changing indirectly what point1 points to because at the end of the day, point1 and point2 are pointing to the same exact location in memory.

So?when you do an assignment between reference types, your are only assigning a reference to the location where the data is stored.?So the two variables are dependent from each others and you need to keep this in mind when you work with C#. If you change point2.X and point2.Y you are also chaning point1.X and point1.Y.?

This is the main differnece between value types and refernece types.

All the numberic data types in C# are value types. Booleans, characters, DateTimes are also value types. Anything that is defined as a struct is a value type in C#.

All value types implicitely inherit from System.ValueType.

Pay attention that some articles online say that value types are usually allocated on the stack. The usually part is very important. They are not alwyas allocated on the stack. Value types are allocated on the stack only when used directly inside methods. This is very efficient because garbage collection doesn't take place so performance is better. However, if you use a value type inside a class or inside an another reference type that it would be allocated on the heap. The memory they are using will be actually collected when the actual reference type will be collected. That's something to keep in mind. The location where the data is allocated (in the stack or the heap) doesn't really matter in terms of what a value type is. What really matters is the semantics. The fact that the value types holds the data withing its own memory allocation.?

What are the reference types?

Strings, arrays, objects and delegates and anything that is a class in C# is a reference type and behaves with this semantic in mind.?Reference types contains pointer to a memory location that holds the data. When you assign reference types you are only assigning a pointer to an another. You are not doing any copy by value.

The good thing about this is that it's extremely efficient to do an assignment between reference types. Insted if you do an assignment between value types it can be expensive especially if the value types takes a lot of bytes in order to be allocated.?

It's a good practice to keep your structs less than 16 bytes.

It's a good practice to make sure your value types are immutable?(so that it's not possible to change the memory that the value types holds after its being created). If you look closely at the .NET Framework, all the value types defined by the framework like DateTime, TimeSpan are immutable. If you call methods on those types, they will return new copies of those types.?

If you are still confused about the two, I recommend you to play with struct and classes.

You can test if a particular type is a value type by using the is operator (is ValueType).?

All reference types implement System.Object.

All value types implement ValueType that indirectly implements System.Object.

If you are considering to take the Microsoft C# specialist certification, this is a very important topic to master because you will be questioned on this. Good luck!

Looking to become a master C# developer?

Get access ot our free Modern C# course.


要查看或添加评论,请登录

Andrea Angella的更多文章

  • 15 reasons why you should learn C# in 2024

    15 reasons why you should learn C# in 2024

    Why you should learn C#? This is the question I want to answer in this article. I am Andrea, a Microsoft MVP, Technical…

    8 条评论
  • The importance of defining performance goals

    The importance of defining performance goals

    This post was originally created in the Productive C# blog in 2016. Let’s start from some questions: Is you application…

  • The Singleton Pattern in .NET – Avoid it if you can!

    The Singleton Pattern in .NET – Avoid it if you can!

    This post was originally created in the Productive C# blog in 2012. The Singleton Pattern ensures a class has only one…

    3 条评论
  • Factory Method Pattern in .NET

    Factory Method Pattern in .NET

    This post was originally written on the Productive C# blog in 2012. There is a little bit of confusion around this…

  • The Command Pattern in .NET

    The Command Pattern in .NET

    The post was originally written on the Productive C# blog in 2012. The Command Pattern encapsulates a request as an…

    4 条评论
  • The Adapter Pattern in .NET

    The Adapter Pattern in .NET

    This post was originally written in the Productive C# blog in 2012. The Adapter Pattern converts the interface of a…

    2 条评论
  • The Facade Pattern in .NET

    The Facade Pattern in .NET

    This post was originally written on the Productiove C# blog in 2012. The Facade Pattern provides a unified interface to…

  • The Template Method Pattern in .NET

    The Template Method Pattern in .NET

    This post was originally written in the Productive C# blog in 2013. The Template Method Pattern defines the skeleton of…

    1 条评论
  • The Iterator Pattern in .NET

    The Iterator Pattern in .NET

    This post was originally written in the Productive C# blog in 2013. The Iterator Pattern provides a way to access the…

    1 条评论
  • Agile Estimation

    Agile Estimation

    This post was originally written on the Productive C# blog in 2020. I'd like to share with you some of my notes after…

    1 条评论

社区洞察

其他会员也浏览了