Tracks
/
C#
C#
/
Syllabus
/
Structs
St

Structs in C#

3 exercises

About Structs

C# structs are closely related classs. They have state and behavior. They can have the same kinds of members: constructors, methods, fields, properties, etc.

Fields and properties can be simple types, structs or reference types. structs observe the same rules about scope, read/write rules and access levels as do classs.

enum Unit
{
    Kg,
    Lb
}

struct Weight
{
    private double count;
    private Unit unit;

    public Weight(double count, Unit unit)
    {
        this.count = count;
        this.unit = unit;
    }

    public override string ToString()
    {
        return count.ToString() + unit.ToString();
    }
}

new Weight(77.5, Unit.Kg).ToString();
// => "77.6Kg"

One of the main things to remember is that when one struct is assigned to a variable or passed as a parameter the values are copied across so changes to the original variable will not affect the copied one and vice versa. In summary, structs are value types.

This article discusses the differences between structs and classs. You will see from the article that structs tend to be lightweight and immutable although this guidance is not enforced (by default) by the compiler or runtime.

There are a couple of things that you will come up against (and about which the compiler will remind you):

  1. Members of a struct cannot be initialized inline.
  2. A struct cannot be inherited
  3. A struct always has a default constructor even if a non-default one is provided, and you cannot provide an explicit parameterless constructor.

As a result of points 1 and 3 above there is no way for the developer of a struct to prevent invalid instances from coming into existence.

Common structs

You will see from the documentation that there is a close relationship between primitives and structs. See Int32/int, for an example. A more conventional example of astructis the type TimeSpan.

Instances of TimeSpan behave much like numbers with comparison operators like > and < and arithmetic operators. You can implement these operators for your own structs when you need them.

One thing to note about TimeSpan is that it implements a number of interfaces e.g. IComparable<TimeSpan>. Although structs cannot be derived from other structs they can implement interfaces.

Equality

Equality testing for structs can often be much simpler than that for classs as it simply compares fields for equality by default. There is no need to override object.Equals() (or GetHashCode()). Remember that if you are relying on Object.GetHashCode() you must still ensure that the fields involved in generating the hash code (i.e. all the fields) must not change while a hashed collection is use. Effectively, this means that structs used in this way should be immutable.

In contrast to the method, Equals(), there is no default implementation of the equality operators, == and !=. If your struct needs them then you will have to implement them.

On the other hand, this article describes how performance can be optimised by creating your own custom Equals() and GetHashCode() method as is often done with classs. The difference in the case of this exercise was about 20% in a not very rigorous comparison but that may be on the low side because all the fields are of the same type - see below.

There are discussions on the web about speed improvements, where the Equals() method is not overridden, if all fields are of the same type. The difference in this exercise of including disparate fields was about 60%. This is not mentioned in Microsoft's documentation so that makes it an un-documented implementation detail, and it should be exploited judiciously.

public bool Equals(Weight other)
{
    return count.Equals(other.count) && unit.Equals(other.unit);
}

public override bool Equals(object obj)
{
    return obj is Weight other && Equals(other);
}

public override int GetHashCode()
{
    return HashCode.Combine(count, unit);
}

General

  • structs: introduction to structs.
  • class-or-struct: lists the guidelines for choosing between a struct and class.
Edit via GitHub The link opens in a new window or tab

Learn Structs

Practicing is locked

Unlock 2 more exercises to practice Structs