Structs in C#

Structs

The Crash Course

  • Structs are very similar to classes. They can be created using the struct keyword instead of the class keyword.
  • Structs are created on the stack instead of the heap, making them faster, performance wise, but it also means that they are passed by value instead of by reference.

Introduction

With an understanding of classes behind us, let's talk about a similar construct: the struct.

The name struct comes from the word "structured", and comes from C++ (which in turn got it from C). It represents a "structured" set of data, or a "record". In C, this was sort of the beginning of object-oriented programming, and lead, ultimately, to the class in C++.

A struct is very similar to a class, and in fact, at first glance, it looks like it is almost the same thing. There's a couple of big differences, though, under the surface.

To really understand structs, it is probably worth going back and taking a look at the Extra Information sections at the end of the tutorial on using classes in C#. It is important to understand the stack vs. the heap, as well as passing by reference vs. passing by value. If you haven't read through that, now's the time to do it.

Creating a struct

Creating a struct is very similar to creating a class. The following code defines a simple struct, and an "identical" class that does the same basic stuff:

struct TimeStruct
{
    private int seconds;
 
    public int Seconds
    {
        get
        {
            return seconds;
        }
        set
        {
            seconds = value;
        }
    }
 
    public int CalculateMinutes()
    {
        return seconds / 60;
    }
}
 
class TimeClass
{
    private int seconds;
 
    public int Seconds
    {
        get
        {
            return seconds;
        }
        set
        {
            seconds = value;
        }
    }
 
    public int CalculateMinutes()
    {
        return seconds / 60;
    }
}

You can see that the two are very similar—in fact the same code is used in both, with the difference being we use the struct keyword to create a struct, while we use the class keyword to create a class.

What's the Difference Between struct and class?

Since the two are so similar, you're probably wondering how the two are different.

One difference is that in a constructor for a class, you can leave some of the data in the class unassigned, and it will take on a value. So for instance, the TimeClass class above could have a constructor that looks like this:

public TimeClass()
{
    // Nothing needs to go here, because the instance variables will just be initialized to 
    // default values (0 for many things).
}

For a struct, though, you have to assign a value to every instance variable:

public TimeStruct() // This part is also broken. See below.
{
    seconds = 0; // This is required, or it won't compile.
}

Another big difference is that with a struct, you can't have a parameterless constructor. Remember with classes that if you don't supply any constructors, a default parameterless one is supplied for you. With a class, you can create any other constructors that you want, as well as provide your own implementation for a parameterless constructor. Adding in any constructor at all makes it so the compiler won't include the default parameterless constructor.

On the other hand, with a struct, there's a default parameterless constructor, but you can't replace it with your own, and adding other constructors doesn't get rid of the default parameterless one.

So from a coding standpoint, there's a few small differences.

Under the hood, though, there's one really substantial difference between structs and classes: structs are value types, while classes are reference types. Recall when we first talked about variables, how we talked about them as being buckets to store information. With a reference type, this bucket contains a reference to a memory location that contains the full data. With value types, the bucket contains all of the data right there in place.

That has some interesting side effects.

For one, it means when you assign two variables the same value, if it's a value type like a struct, they each end up with a complete copy of the data. Modifying one doesn't affect the other. With a reference type like a class, they each have their own copy of the reference, but in both cases, the references point to the same spot in memory. With a value type like a class, when you modify one, you can see the changes through the other variable's reference.

It takes some getting used to.

It's important to keep in mind which of the types you're using are reference types and which are value types, because they behave so differently from each other.

And for what it's worth, I should state that most of the built-in types, including int, long, short, byte, char, bool, double, float, and decimal, as well as enumerations and anything you define as a struct, are all value types. string, arrays, and anything you define as a class are all reference types. (You've been using both value and reference types all along!)

What's Next?

The struct type is very similar to a class, but it has a couple of key differences. In particular, that it is created ("allocated") on the stack instead of the heap. This means it is faster, and it also means that it is passed by value, so a copy of the struct is sent to a method instead of sending the actual original struct.

It's kind of a nice little feature of the language, and it is worth knowing they exist, but you will likely end up using classes way more often than you will structs.

The next thing for us to look at is some of the more advanced features of classes. These features give us a whole lot of power in how we reuse code, and organize our entire program. The first of these is inheritance.