C# - Struct

We have learned class in the previous section. Class is a reference type. C# includes a value type entity same as class called "structure". Structs are mainly useful to hold small data values. A structure can be defined using the struct operator. It can contain parameterized constructor, static constructor, constants, fields, methods, properties, indexers, operators, events and nested types.

Structure Declaration

A structure is declared using struct keyword with public, private, or internal modifier. The default modifer is internal for the struct and its members.

The following declares the simple structure that holds data for employees.

Example: Structure
struct Employee
{
    public int EmpId;
    public string FirstName;
    public string LastName;
}

A struct object can be created with or without the new operator, same as primitive type variables. When you create a struct object using the new operator, an appropriate constructor is called.

Example: Create struct object using new keyword
struct Employee
{
    public int EmpId;
    public string FirstName;
    public string LastName;
}

Employee emp = new Employee();
Console.Write(emp.EmpId); // prints 0  

In the above code, an object of the structure Employee is created using the new keyword. So, this calls the default parameterless constructor that initializes all the members to their default value.

When you create a structure object without using new keyword, it does not call any constructor and so all the members remain unassigned. So, you must assign values to each member before accessing them, otherwise it will give a compile time error.

Example: Create struct object without using new keyword
struct Employee
{
    public int EmpId;
    public string FirstName;
    public string LastName;
}

Employee emp;
Console.Write(emp.EmpId); // Compile time error  

emp.EmpId = 1;
Console.Write(emp.EmpId); // prints 1  

Constructors in Struct

A struct cannot contain parameterless constructor. It can only contain parameterized constructors or a static constructor. You can declare parameterized constructor to initialize struct members, as shown below.

Example: Parameterized Constructor in Struct
struct Employee
{
    public int EmpId;
    public string FirstName;
    public string LastName;

    public Employee(int empid, string fname, string lname)
    {
        EmpId = empid;
        FirstName = fname;
        LastName = lname;
    }
}

Employee emp = new Employee(10, "Bill", "Gates");

Console.Write(emp.EmpId); // prints 10  
Console.Write(emp.FirstName); // prints Bill  
Console.Write(emp.LastName); // prints Gates  

Please note that you must assign values to all the members of a struct in parameterized constructor, otherwise it will give compile time error if any member remains unassigned.

A struct can include static parameterless constructor and static fields.

Example: Static Constructor in Struct
struct Employee
{
    public int EmpId;
    public string FirstName;
    public string LastName;

    static Employee()
    {
        Console.Write("First object created");
    }

    public Employee(int empid, string fname, string lname)
    {
        EmpId = empid;
        FirstName = fname;
        LastName = lname;
    }
}

Employee emp1 = new Employee(10, "Bill", "Gates");
Employee emp2 = new Employee(10, "Steve", "Jobs");

Methods and Properties in Struct

The structure can contain properties, auto-properties, or methods, same as class.

Example: Methods and Properties in Struct
struct Employee
{
    public int EmpId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Employee(int empid, string fname, string lname)
    {
        EmpId = empid;
        FirstName = fname;
        LastName = lname;
    }

    public string GetFullName()
    {
        return FirstName + " " + LastName;
    }
}

Employee emp = new Employee(10, "Bill", "Gates");

Console.Write(emp.GetFullName()); // prints Bill Gates  

Events in Struct

A struct can contain events to notify subscriber about some action. Consider the following example.

Example: Structure
struct Point
{
    private int _x, _y;

    public int X 
    {
        get 
        {
            return _x;
        }

        set 
        {
            _x = value;
            PointChanged(_x);
        }
    }

    public int Y
    {
        get
        {
            return _y;
        }
        set
        {
            _y = value;
            PointChanged(_y);
        }
    }

    public event Action<int> PointChanged;
}

The above structure contains private fields _x and _y, properties X and Y and PointChanged event to notify if points change. Notice that we raise the PointChanged event whenever X or Y changes. The following code handles the PointChanged event.

Example: Handle Structure Events
class Program
{
    static void StructEventHandler(int point)
    {
        Console.WriteLine("Point changed to {0}", point);
    }

    static void Main(string[] args)
    {
        Point.StaticMethod();

        Point p = new Point();
        
        p.PointChanged += StructEventHandler;
        p.X = 10;
    }
}

A struct is a value type so it is faster than a class object. Use struct whenever you want to just store the data. Generally structs are good for game programming. However, it is easier to transfer a class object than a struct. So do not use struct when you are passing data across the wire or to other classes.

Characteristics of Structure:

  • Structure can include constructors, constants, fields, methods, properties, indexers, operators, events & nested types.
  • Structure cannot include parameterless constructor or destructor.
  • Structure can implement interfaces, same as class.
  • A structure cannot inherit another structure or class, and it cannot be the base of a class.
  • Structure members cannot be specified as abstract, virtual, or protected.

Difference between Struct and Class:

  • Class is reference type whereas struct is value type
  • Struct cannot declare a default constructor or destructor. However, it can have parametrized constructors.
  • Struct can be instasntiated without the new operator. However, you won't be able to use any of its methods, events or properties if you do so.
  • Struct cannot be used as a base or cannot derive another struct or class.