Enums and Structs
Enums (enum)
An enum is a value type used to define a set of named constants, making code more readable and type-safe.
Defining an Enum
Use the enum keyword to define an enum. The default underlying type is int, starting from 0 and incrementing.
Example
enum Season
{
Spring,
Summer,
Autumn,
Winter
}
class Program
{
static void Main()
{
Season current = Season.Autumn;
System.Console.WriteLine(current);
System.Console.WriteLine((int)current);
}
}
Autumn
2
Underlying Type and Explicit Assignment
The underlying type of an enum defaults to int. You can explicitly specify another integer type and assign specific values to members.
Example
enum Priority : byte
{
Low = 1,
Medium = 2,
High = 3
}
enum HttpStatusCode
{
OK = 200,
NotFound = 404,
InternalServerError = 500
}
class Program
{
static void Main()
{
Priority p = Priority.High;
System.Console.WriteLine((byte)p);
System.Console.WriteLine((int)HttpStatusCode.NotFound);
}
}
3
404
Enum Conversion
Enums and their underlying types can be explicitly cast to each other.
Example
enum Season
{
Spring,
Summer,
Autumn,
Winter
}
class Program
{
static void Main()
{
Season s = Season.Spring;
int value = (int)s;
System.Console.WriteLine(value);
Season fromInt = (Season)2;
System.Console.WriteLine(fromInt);
}
}
0
Autumn
Enum Class Methods
The System.Enum class provides several static methods for enum operations.
Common Methods
| Method | Description |
|---|---|
Enum.Parse |
Converts a string to an enum; throws an exception on failure |
Enum.TryParse |
Converts a string to an enum; returns false on failure |
Enum.GetName |
Gets the name of an enum value |
Enum.GetValues |
Gets all enum values |
Enum.IsDefined |
Determines whether a value is defined in the enum |
Example
enum Season
{
Spring,
Summer,
Autumn,
Winter
}
class Program
{
static void Main()
{
Season parsed = (Season)Enum.Parse(typeof(Season), "Summer");
System.Console.WriteLine(parsed);
bool ok = Enum.TryParse<Season>("Winter", out Season result);
System.Console.WriteLine($"{ok}, {result}");
string name = Enum.GetName(typeof(Season), 2);
System.Console.WriteLine(name);
foreach (Season s in Enum.GetValues(typeof(Season)))
{
System.Console.WriteLine($"{s} = {(int)s}");
}
System.Console.WriteLine(Enum.IsDefined(typeof(Season), 1));
System.Console.WriteLine(Enum.IsDefined(typeof(Season), 99));
}
}
Summer
True, Winter
Autumn
Spring = 0
Summer = 1
Autumn = 2
Winter = 3
True
False
Structs (struct)
A struct is a value type suitable for encapsulating small amounts of data. Structs are stored on the stack, and assignment copies the entire value.
Defining a Struct
Use the struct keyword to define a struct.
Example
struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
public override string ToString()
{
return $"({X}, {Y})";
}
}
class Program
{
static void Main()
{
Point p1 = new Point(3, 4);
Point p2 = p1;
p2.X = 10;
System.Console.WriteLine(p1);
System.Console.WriteLine(p2);
}
}
(3, 4)
(10, 4)
Struct vs Class
Structs and classes have important differences in semantics and behavior.
Comparison
| Feature | struct | class |
|---|---|---|
| Type category | Value type | Reference type |
| Storage location | Stack | Heap |
| Assignment behavior | Copies value | Copies reference |
| Inheritance | Not supported (cannot be inherited) | Supported |
| Interfaces | Can implement | Can implement |
| Destructor | None | Yes |
| Default value | All fields zero-valued | null |
Example
struct PointStruct
{
public int X;
public int Y;
}
class PointClass
{
public int X;
public int Y;
}
class Program
{
static void Main()
{
PointStruct s1 = new PointStruct();
PointStruct s2 = s1;
s2.X = 5;
System.Console.WriteLine($"struct: s1.X={s1.X}, s2.X={s2.X}");
PointClass c1 = new PointClass();
PointClass c2 = c1;
c2.X = 5;
System.Console.WriteLine($"class: c1.X={c1.X}, c2.X={c2.X}");
}
}
struct: s1.X=0, s2.X=5
class: c1.X=5, c2.X=5
When to Use Structs
Structs are not always better than classes. Consider using a struct when:
- The data is small (recommended ≤16 bytes)
- It logically represents a single value (e.g., coordinates, color)
- It has a short lifetime with frequent creation and destruction
- Inheritance is not needed
Common examples: Point, Color, DateTime, TimeSpan.
readonly struct (C# 7.2+)
readonly struct ensures all fields are immutable. The compiler prevents any modification operations.
Example
readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y)
{
X = x;
Y = y;
}
public double DistanceTo(Point other)
{
int dx = X - other.X;
int dy = Y - other.Y;
return System.Math.Sqrt(dx * dx + dy * dy);
}
}
class Program
{
static void Main()
{
Point p1 = new Point(3, 4);
Point p2 = new Point(0, 0);
System.Console.WriteLine(p1.DistanceTo(p2));
}
}
5
record struct (C# 10+)
record struct combines the value semantics of a struct with the value equality and concise syntax of a record, suitable for scenarios requiring immutability and auto-generated members.
Example
record struct Point(int X, int Y);
class Program
{
static void Main()
{
Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);
System.Console.WriteLine(p1 == p2);
System.Console.WriteLine(p1 with { X = 10 });
}
}
True
Point { X = 10, Y = 2 }
record struct auto-generates Equals, ToString, with expression, and other members, reducing boilerplate code.
❓ FAQ
📖 Summary
- Enums are defined with
enum, default underlying type isint, incrementing from 0 - Underlying type and member values can be explicitly specified
Enum.Parse/TryParse/GetName/GetValues/IsDefinedprovide enum operations- Enums and underlying types can be explicitly cast to each other
- Structs are defined with
struct, are value types, stored on the stack - Struct assignment copies the value; class assignment copies the reference
- Structs cannot be inherited but can implement interfaces
- Suitable scenarios: small data (≤16 bytes), immutable, short lifetime
readonly struct(C# 7.2+) ensures all fields are immutablerecord struct(C# 10+) combines value semantics with record's concise syntax
📝 Exercises
- Define an
enum Direction { North, East, South, West }, write code to iterate over all directions and output the name and integer value - Define a
struct Rectanglewith width and height, provide a method to calculate area, and verify that assignment copies the value - Change the
Rectanglefrom the previous exercise to areadonly struct, ensuring all fields are read-only and initialized through the constructor - Use
Enum.TryParseandEnum.IsDefinedto write a safe enum parsing method that takes a string and returns the corresponding enum value or a default value - Write code to compare the behavioral difference between
structandclasswhen passed as method parameters (value passing vs reference passing)



