public struct Employee
  {
    public string Name { get; set; }
    public string Department { get; set; }

    public override string ToString()
    {
        return Name + " works in " + Department;
    }
  }
  

1. What is the struct keyword?

The struct keyword in C# is used for creating a structure.

A structure is similar to a class and is used to hold values of different types under one home.

Like a class, it can contain a static constructor, a parameterized constructor, constants, fields, methods, properties, operators, indexers, nested types and events.

Its purpose is to represent a record. A blueprint that defines the variables to describe an object. For example, an employee structure may store basic employee details like “Name” and “Department”.

Despite its similarity to a class, there are subtle differences that we will explore in this article.

2. What are structures used for in C#?

Structures are suitable for storing simple, low value objects that tend to be manipulated often such as int or bools.

But don’t classes do that already? The raison d'être of structures lies in one word: performance.

That's because of how they manage memory. Structs are value types whereas classes are reference types. Classes are allocated seperate memory on the managed heap whereas structs occupy the evaluation stack.

Don't worry if that didn't make a great deal of sense! What it means in practical terms is that you do not create a new instance of struct using the new keyword. It is used like a value type such as int. THIS IS NOT CORRECT?? SEE NEXT SECTION

This saves time when retrieving/modifying your variables, as they are accessed directly without needing to fetch via a reference.

This does have some implications as we'll see later.

This time improvement is not really going to make a difference for many of your usual application use cases. But can prove crucial for programs where speed is critical, such as in video games.

__So, shouldn’t I always use a struct instead of class? __

No, there are several limitations to structs and generally, you will use classes unless your application needs you to measure and track performance.

3. How to use the struct keyword?

Here is a small console program containing employee data and a console program that creates and populates some structs.

Structures tend to be more performant than classes but what are the trade offs?

4.1 structures cannot inherit from another structure or from an object

There is one exception - the base Object type, from which it inherits automatically.

This means that we can inherit from the few Object methods like .ToString(). Let's try it:

 public struct Employee
  {
    public string Name { get; set; }
    public string Department { get; set; }

    public override string ToString()
    {
        return Name + " works in " + Department;
    }
  }
  

This let's us to something like

Employee Federica = new Employee() { Prenom = "Federica", Department = “Bio-Sciences” };
Console.WriteLine(Federica.ToString());

OUTPUT:

Federica works in Bio-Sciences

Feel free to give it a try yourself and modify the fiddle above.

4.2 structures can't use default constructors

Like classes, it is possible to have constructors on a structure. Unlike class, this doesn't include the default constructor.

public struct Employee
  {
      // default constructor will trigger compilation error 	
      public Employee()
      {
      }
  }

However, include a parameter and this works:

public struct Employee
  {
      public string name

      public Employee(string name)
      {
            this.name = name;
      }
  }
  Employee employee = new Employee(”Benjamin”);

4.3 Object fields & Properties must be initialised before using them in the constructor

Be careful using a property in the constructor.

public struct Employee
{
    private int employeeNumber { get; set; }

    public Employee(int employeeNumber)
    {
          AssignNumber(employeeNumber);
    }

	private void AssignNumber(int employeeName)
    {
          employeeNumber = employeeName;
    }
}
}

The above code will cause the following compilation errors.

 The 'this' object cannot be used before all of its fields are assigned to 
Backing field for automatically implemented property 'Employee.name' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.

To correct this error, you can can change the constructor definition and call the parameterless contructor from your parameterized one by doing : this().

The default constructor takes care of initializing all the variables of a class or structure.

public struct Employee
{
    private int employeeNumber { get; set; }

    public Employee(int employeeNumber): this()
    {
        AssignNumber(employeeNumber);
    }

	private void AssignNumber(int employeeName)
    {
          employeeNumber = employeeName;
    }
}

Good struct practice is that they should be 16 bits or less and immutable. If you are going to change object fields after creating them, consider refactoring your struct to a class.

4.4 Switching structures in parameters must use ref directly

A struct is a value type and each time we pass a structure into parameters of a method, a copy of the object will be made.

Observe the following code:

static void Main(string[] args)
{
    // Person is our struct
    Person federica = new Person() { Age = 28 };
    IncreaseAge(federica);
    Console.WriteLine(federica.Age);
}

private static void IncreaseAge(Person person)
{
    person.Age++;
}

This code will still output 28 even despite altering the age of the person in the method IncreaseAge.

That's because IncreaseAge method is working on a copy of the structure.

This of course means that if we want to change a structure from a method, we will have to use the keyword ref:

static void Main(string[] args) { Personne nicolas = new Personne() { Age = 30 }; FaitVieillir(ref nicolas); Console.WriteLine(nicolas.Age); }

private static void FaitVieillir(ref Personne personne) { personne.Age++; }

This applies to all value types.

Be careful, though. If the structure is very large, making a copy of it every time you use a method can be particularly time-consuming and can disrupt your application's performance.

5. Differences between Class and Structure

Some of these differences were covered in the limitations section.

  • Classes support inheritance whereas Structure do not.
  • Classes can have both a default and defined constructor whereas Structures only supports defined constructors.
  • Classes are reference type data type whereas Structure is a value types data type.
  • Classes can have protected data members whereas structures can only have public data members.

6. When should we use a struct over a class?

We can turn straight to Microsoft's .NET documentation for guidance:

What I've deduced it down to is this:

Define a structure if:

  1. The instances of the type are small, similar to primitive types (integer, double, bool)
  2. You want value semantics as opposed to reference semantics.
  3. It is immutable
  4. It has an instance size smaller than 16 bytes.
  5. Doesn't need to be boxed frequently.
  6. No need for polymorphism
  7. Want to avoid heap allocation and the related garbage collection overhead.

Keep in mind, that when it comes to performance, classes could still end up faster in practice. as passing structs as arguments is more expensive than classes. (section 4.3).