C# Structs (structures) Tutorial

In this tutorial we learn about data structures that can store collections of different data types as well as functions. Structs are simpler, but a more performant version of classes.

We cover how to define and access a struct as well as the differences between classes and structs.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What is a Struct

A struct, or structure, is used to store collections of different data types as well as functions. Think of a struct as a variable that holds multiple types of values and functions.

A struct is a value type and is stored on the stack. A struct is usually more performant than a class.

How to define a Struct

To define a struct we use the struct keyword, followed by a name and a code block. The code block must be terminated with a semicolon.

Syntax:
struct identifier
{
    // struct body
};
Example:
struct Player
{

};

As mentioned above, a struct can hold variables and functions. We define our variables and functions inside the body of the struct.

Example:
using System;

namespace Structs
{
    class Program
    {
        static void Main(string[] args)
        { }

        struct Player
        {
            public string name;
            public int hitPoints;
            public float moveSpeed;

            public void Booster(bool boost)
            {
                if (boost)
                    moveSpeed *= 2;
            }
        }

    } // end class
} // end namespace

In the example above, we define multiple types of variables and a function that modifies one of those variables on a condition.

Note that we use the keyword public. public is an access modifier that defines the scope of the variable or function inside a struct or class as openly accessible. We cover it again in the lesson on access modifiers .

How to access a Struct

Before we can access a struct, we need to create a new instance of it. For a struct, we need to use the struct name as a type.

Syntax:
structIdentifier identifier = new structIdentifier();

For example, if our struct is called Player, we use Player as the type.

Example:
Player player1 = new Player();

Once, we have a new object, we can access the variables and functions inside with dot notation.

Syntax:
identifier.field/function

For example, if we wanted to access the name variable from the Player struct, we would write .name after the object.

Example:
player1.name // Access name inside Player
Example:
using System;

namespace Structs
{
    class Program
    {
        static void Main(string[] args)
        {
            Player player1 = new Player();

            player1.name = "Player 1";
            player1.hitPoints = 100;
            player1.moveSpeed = 5f;

            // Player picked up booster
            // increase moveSpeed
            player1.Booster(true);

            Console.WriteLine("Ready: {0}", player1.name);
            Console.WriteLine("HP: {0}", player1.hitPoints);
            Console.WriteLine("Speed: {0}", player1.moveSpeed);
            Console.ReadLine();
        }

        struct Player
        {
            public string name;
            public int hitPoints;
            public float moveSpeed;

            public void Booster(bool boost)
            {
                if (boost)
                    moveSpeed *= 2;
            }
        }

    } // end class
} // end namespace

Let’s break down the example above step by step:

  1. Below our Main() function, we created a struct, called Player, with some variables and a function inside of it.
  2. In the Main() function, we create a new object from the struct called player1.
  3. We access the variables inside the struct and assign them some values. We use the object name (player1) with a dot operator and the variable we want to assign a value to.
  4. Next, we call the Booster() function from the struct in the same manner.
  5. Finally we print out the variables that we assigned values to.

It’s possible to have multiple instances of the same struct. We just create another instance of the struct with a different name.

Example:
using System;

namespace Structs
{
    class Program
    {
        static void Main(string[] args)
        {
            Player player1 = new Player();
            Player player2 = new Player();

            player1.name = "Mario";
            player1.hitPoints = 100;
            player1.moveSpeed = 5f;

            player2.name = "Luigi";
            player2.hitPoints = 100;
            player2.moveSpeed = 5f;

            Console.WriteLine("Ready: {0}", player1.name);
            Console.WriteLine("HP: {0}", player1.hitPoints);
            Console.WriteLine("Speed: {0}\n", player1.moveSpeed);

            Console.WriteLine("Ready: {0}", player2.name);
            Console.WriteLine("HP: {0}", player2.hitPoints);
            Console.WriteLine("Speed: {0}", player2.moveSpeed);
            Console.ReadLine();
        }

        struct Player
        {
            public string name;
            public int hitPoints;
            public float moveSpeed;

            public void Booster(bool boost)
            {
                if (boost)
                    moveSpeed *= 2;
            }
        }

    } // end class
} // end namespace
Class vs Struct

Structures in C# are different from those in traditional C or C++. Classes and structs in C# have the following basic differences:

  • A struct is a value type and lives on the stack, a class is a reference type and lives on the heap.
  • A struct can’t have a default constructor.
  • A struct can’t inherit from other structs and can’t be used as a base to be inherited from.
  • A struct’s members can’t be specified as abstract, virtual or protected.
  • A struct can be instantiated without using the new operator.

Summary: Points to remember

  • A struct can hold multiple data containers, like variables, as well as functions.
  • A struct is like a class but simpler and slightly more performant.
  • Before we can use a struct, we must create a new object instance of it.
  • Variables and functions inside a struct are accessed with dot notation.
  • We can create multiple new instances of a struct.