In the previous articles, we have learned about classes, how to use them and how to create an object as an instance of a class. In this article, we are going to talk about structures that are similar to classes but have some differences as well.
If you want to see the complete navigation of this tutorial, you can do that here C# Intermediate Tutorial.
To download the source code, you can visit Structures in C# Source Code.
We are going to split this article into the following sections:
- Working with Structures
- Structure Declaration
- Differences Between Classes and Structures
- When to Use Structure Instead of a Class
- Conclusion
Working with Structures
A structure is a value type, in the opposite of a class which is a reference type, and it has its own fields, methods, and constructors like a class.
Maybe you didn’t realize, but we have worked with structures in our previous articles, especially in module 1 C# basics. Int, double, decimal, bool type etc. are all aliases for the structures System.Int32, System.Int64 etc. In a table below, we can see the primitive types and what are they built from (class or structure):
Structure Declaration
To declare our own structure, we need to use the struct
keyword followed by the name of the type and then the body of the structure between two curly braces:
public struct Time { private int _hours, _minutes, _seconds; }
We can create our own constructor to initialize our private fields:
public struct Time { private int _hours, _minutes, _seconds; public Time(int hours, int minutes, int seconds) { _hours = hours; _minutes = minutes; _seconds = seconds; } public void PrintTime() { Console.WriteLine($"Hours: {_hours}, Minutes: {_minutes}, Seconds: {_seconds}"); } }
To access our structure we can use this syntax:
static void Main(string[] args) { Time time = new Time(3, 30, 25); time.PrintTime(); Console.ReadKey(); }
Differences Between Classes and Structures
- The structure is a value type, while the class is a reference type
- We can’t declare our own default constructor in a structure. That’s because a structure is always generating a default constructor for us. In a class, we can create a default constructor because a class won’t generate then one for us
- We can initialize fields in our structure by creating a non-default constructor, but we must initialize all of the fields inside that constructor. It is not allowed to left a single field without a value:
With a class, this is not a case
- In a class, we can initialize instance fields at their point of declaration. In a structure, we cannot do that:
- An instance of a class lives on a heap memory while the instance of a structure lives on a stack
- In a structure, we can create a non-default constructor, but nevertheless, the compiler will always generate the default one. This is not the case with a class.
When to Use Structure Instead of a Class
The general rule that we can follow is that our structures need to be small and simple types and above all immutable. For anything else, we should use a class.
Why is immutability so important?
Well let’s take a look at this example:
class Test { public int Number { get; set; } public Test(int number) { Number = number; } } class Program { static void Main(string[] args) { Test test = new Test(10); Console.WriteLine(test.Number); ChangeNumber(test); Console.WriteLine(test.Number); } public static void ChangeNumber(Test test) { test.Number = 45; } }
If we inspect the result, we will see printed out 10 and 45. And that is the correct result. But if we change our Test class to be a structure and then inspect the result, we will see 10 and 10.
This can lead to confusion and problems as well, because the consumer may expect that the ChangeNumber
method would modify the Number
property because we allowed it in the code. But if we create properties or fields immutably (as read-only in a structure) then we can avoid this kind of confusion. The consumer can assign values to the properties by calling the constructor method but after that those properties need to stay immutable.
Conclusion
In this article, we have learned:
- What structures in C# are and how to create them
- About structures limitations
- When to use structures in your C# code
In the next article, we are going to talk about Enumerations in C#.
The downside of classes is that both code and data are thrown onto the heap…with a struct, only data is allocated. So if your class has many methods, and you start allocating many instances of the class, your memory will take a hit.
Thank you Ben for this. It is great to know stuff like that. All the best.