C# Value Types, Enums, and Structs

Last Updated: Nov 05, 2025
2 min read
Legacy Archive
Legacy Guidance: This article preserves historical web development content. For modern .NET 8+ best practices, visit our Tutorials section.

Unified Type System at a Glance

C# puts every type under one roof called the unified type system. You get value types, reference types, and pointer types. This page focuses on value types. They are simple, fast, and stored on the stack. When a value type goes out of scope it is removed automatically. You copy a value type by assignment, which creates a new copy.

Simple Types

Simple types are the built-in numeric and logical types. Each C# keyword maps to a .NET type. For example: int → System.Int32, bool → System.Boolean, byte → System.Byte, char → System.Char, float → System.Single, double → System.Double, decimal → System.Decimal, short → System.Int16, long → System.Int64, sbyte → System.SByte, ushort → System.UInt16, uint → System.UInt32, ulong → System.UInt64. Strings are reference types, not value types.

Declaring common value types
int count = 10;
long big = 9_223_372_036_854_775_807L;
bool isReady = true;
char letter = 'A';
float ratio = 1.5f;
double price = 19.99;
decimal money = 20.50m;
byte flags = 0b_1010_1100;
ushort port = 8080;
uint version = 1u;
ulong mask = 0UL;

Note: string is a reference type. Arrays are reference types too.

Enumerations

An enumeration groups related named constants. You declare it with the enum keyword and a backing integral type. If you do not specify values, C# starts at 0 and increases by 1. You can set the first value or any specific member when you need stable numbers.

Enum basics
public enum Status // backing type int by default
{{ 
    None,   // 0
    Started,// 1
    Done    // 2
}}

public enum HttpCode : short
{{
    Ok = 200,
    NotFound = 404,
    ServerError = 500
}}

// Cast when storing in variables
short code = (short)HttpCode.Ok;
Custom start value
public enum Priority
{{
    Low = 10,    // starts at 10
    Medium,      // 11
    High = 53    // explicit value
}}

Structures

A struct is a lightweight type that bundles fields and members. It behaves like a value. You can add constructors, methods, properties, operators, and events. Use a struct for small, immutable data where copying is cheap. Prefer a class when the data is large, needs inheritance, or must be shared by reference.

Struct example
public readonly struct Point2D
{{   
    public int X {{ get; }}
    public int Y {{ get; }}

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

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

var p1 = new Point2D(3, 4);
Console.WriteLine(p1);

Practical Tips

  • Prefer readonly struct for small immutable records.
  • Use ref or in when you need to pass large structs without copying.
  • Avoid accidental boxing of value types into object.
  • Enums improve readability and reduce magic numbers.

Quick tips: choose an enum when you need a set of named numbers. Prefer readonly structs for small data records. Avoid boxing and unboxing by keeping value types in their native form. When you pass a value type to a method it is copied, unless you use ref or in.

FREQUENTY ASKED QUESTIONS (FAQ)

When should I use a struct instead of a class?

When should I use a struct instead of a class? Use a struct for small sets of numeric or coordinate like data where copying is cheap and you do not need inheritance. Otherwise use a class.

Are enums value types?

Are enums value types? Yes. An enum has an underlying integral type and is a value type.

What is the default value of value types?

What is the default value of value types? Fields of value types default to zeroed values. Local variables must be assigned before use.

Back to Articles