Codectionary / Developer documentation / C#

Structs

A struct is a value type, defined much like a class but with a key difference: structs are copied by value when assigned or passed to a method, while classes are copied by reference. This makes structs efficient for small, simple data groupings (like coordinates or colors) where copy semantics are actually desirable, avoiding heap allocation and garbage collection overhead.

Syntax

struct StructName {\n  // fields, properties, methods\n}

Examples

Basic Struct

Defining and using a simple struct.

public struct Point
{
    public int X, Y;

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public override string ToString() => $"({X}, {Y})";
}

Point p = new Point(3, 4);
Console.WriteLine(p);  // (3, 4)

Value Semantics: Copied, Not Referenced

The key difference from a class - assigning a struct copies its data completely.

public struct Point
{
    public int X, Y;
    public Point(int x, int y) { X = x; Y = y; }
}

Point original = new Point(1, 1);
Point copy = original;  // this COPIES the entire struct

copy.X = 99;

Console.WriteLine(original.X);  // 1 - unaffected by the change to copy
Console.WriteLine(copy.X);       // 99

// Compare to a class, where "copy" would just be another reference
// to the SAME object, and changing copy.X would also change original.X

record struct (C# 10+)

Combining record-style value equality and concise syntax with struct's value-type copy semantics.

public record struct Point(int X, int Y);

Point p1 = new Point(3, 4);
Point p2 = new Point(3, 4);

Console.WriteLine(p1 == p2);  // true - value equality, like a record
Console.WriteLine(p1);         // Point { X = 3, Y = 4 }

Best practices

  • Use structs for small, immutable data groupings (roughly 16 bytes or less is a common guideline) where value-copy semantics make sense, like coordinates or RGB colors
  • Use classes instead of structs for anything larger or that represents an entity with identity (a Customer, an Order) rather than a simple value
  • Be aware that passing a large struct around by value can hurt performance due to repeated copying - pass by "in" or "ref" if a large struct must avoid copies
  • Consider record struct (C# 10+) when you want both value equality and value-type copy semantics together

At a glance

Purpose
Applications on the .NET platform
File extension
.cs
Runs in
.NET runtime
Usually used with
.NET SDK and libraries

Specifications & further reading

Related C# documentation

Classes & Objects
A class is a blueprint for creating objects, bundling related data (fields/properties) and behavior (methods) together. C# is a fully object-oriented language - every application has at least one class, typically with a Main method as its entry point. An object is a specific instance of a class, created with the new keyword, with its own independent copy of the class's instance data.
Constructors
A constructor is a special method that runs automatically when an object is created with new, used to initialize the object's state. A constructor shares its name with the class and has no return type. C# supports constructor overloading (multiple constructors with different parameter lists) and constructor chaining with this(...), where one constructor calls another in the same class to avoid duplicating initialization logic.
Properties (get/set)
Properties are C#'s idiomatic way to expose class data through accessor-like syntax while still allowing controlled access via get and set. Unlike a plain public field, a property can validate a value before it's set, compute a value on the fly, or restrict access to read-only. Auto-implemented properties (using { get; set; } with no body) provide a concise shorthand when no custom logic is needed.
Access Modifiers
Access modifiers control the visibility of classes, fields, methods, and properties from other parts of a program. C# provides public (accessible from anywhere), private (accessible only within the declaring class - the default for class members), protected (accessible within the class and its subclasses), internal (accessible only within the same assembly/project), and combinations like protected internal and private protected.