0
0
C Sharp (C#)programming~15 mins

Underlying numeric values in C Sharp (C#) - Deep Dive

Choose your learning style9 modes available
Overview - Underlying numeric values
What is it?
Underlying numeric values are the actual numbers stored in memory that represent named constants like enums in C#. Each named constant corresponds to a specific number, usually an integer. This helps the computer understand and work with these names as numbers behind the scenes. Knowing these values lets you convert between names and numbers easily.
Why it matters
Without underlying numeric values, named constants like enums would be just words with no meaning to the computer. This would make it impossible to store, compare, or perform calculations with them. Understanding these values helps you debug, optimize, and use enums effectively in programs, making your code clearer and more reliable.
Where it fits
Before learning underlying numeric values, you should understand basic data types and enums in C#. After this, you can learn about bit flags, type casting, and advanced enum usage like custom underlying types and attributes.
Mental Model
Core Idea
Every named constant in C# enums is stored as a specific number called its underlying numeric value, which the computer uses to represent it internally.
Think of it like...
Think of a parking lot where each parking spot has a number. The spot's number is the underlying numeric value, while the car's license plate is like the named constant. The number tells you exactly where the car is parked, even if you only know the license plate.
Enum Color {
  Red = 0,
  Green = 1,
  Blue = 2
}

Memory stores:
[0] -> Red
[1] -> Green
[2] -> Blue

Access by name or number:
Red <-> 0
Green <-> 1
Blue <-> 2
Build-Up - 7 Steps
1
FoundationWhat are enums and named constants
πŸ€”
Concept: Introduce enums as named groups of constants representing numbers.
In C#, an enum is a way to give names to numbers. For example: enum Days { Sunday, Monday, Tuesday } Here, Sunday, Monday, and Tuesday are names for numbers 0, 1, and 2 by default.
Result
You can use Days.Monday in code, which means the number 1 internally.
Understanding enums as named numbers helps you see how code becomes easier to read and maintain.
2
FoundationDefault underlying numeric values in enums
πŸ€”
Concept: Explain how C# assigns numbers starting from zero by default.
If you don't assign numbers, C# starts numbering enum members from 0 upwards: enum Status { Off, On, Unknown } Off = 0, On = 1, Unknown = 2 automatically.
Result
Status.On has the underlying numeric value 1.
Knowing default numbering prevents confusion when you see numbers in debugging or output.
3
IntermediateCustom underlying numeric values
πŸ€”
Concept: Show how to assign specific numbers to enum members.
You can set numbers explicitly: enum Level { Low = 10, Medium = 20, High = 30 } Now Low is 10, Medium is 20, High is 30.
Result
Level.Medium has the underlying numeric value 20.
Custom values let you match enums to real-world codes or protocols.
4
IntermediateChanging the underlying type of enums
πŸ€”
Concept: Explain that enums can use different numeric types like byte or long.
By default, enums use int (32-bit integer). You can specify another type: enum Flags : byte { None = 0, Read = 1, Write = 2 } This saves memory or matches external data formats.
Result
Flags.Read is stored as a byte with value 1.
Choosing the right underlying type optimizes memory and compatibility.
5
IntermediateCasting enums to numeric values
πŸ€”Before reading on: do you think you can convert an enum to its number directly or do you need special methods? Commit to your answer.
Concept: Show how to get the numeric value from an enum using casting.
You can cast an enum to its underlying number: Level lvl = Level.High; int num = (int)lvl; // num is 30 This lets you use the number in calculations or output.
Result
Casting Level.High to int gives 30.
Knowing casting lets you bridge between human-readable names and machine numbers.
6
AdvancedCasting numeric values back to enums
πŸ€”Before reading on: do you think casting any number to an enum always gives a valid named constant? Commit to your answer.
Concept: Explain how to convert numbers back to enums and the risks involved.
You can cast numbers to enums: int num = 20; Level lvl = (Level)num; But if num doesn't match a named constant, lvl holds that number without a name. Example: Level unknown = (Level)25; // 25 has no name in Level enum
Result
Casting 20 to Level gives Level.Medium, but 25 gives an unnamed value.
Understanding this prevents bugs when reading data that might not match enum names.
7
ExpertFlags enums and bitwise underlying values
πŸ€”Before reading on: do you think enum values in Flags enums must be sequential numbers or can they be powers of two? Commit to your answer.
Concept: Show how underlying numeric values represent combinations using bits in Flags enums.
Flags enums use powers of two so values can combine: [Flags] enum Permissions { None = 0, Read = 1, Write = 2, Execute = 4 } You can combine: Permissions p = Permissions.Read | Permissions.Write; // value 3 The underlying number 3 means both Read (1) and Write (2) are set.
Result
Combined flags have underlying numeric values that add up bitwise.
Knowing bitwise values unlocks powerful ways to store multiple options efficiently.
Under the Hood
Enums in C# are stored as numeric values in memory, typically as integers or other integral types. Each named constant corresponds to a fixed number stored in the program's data. When you use an enum in code, the compiler replaces the name with its numeric value. Casting between enums and numbers is just reading or writing these stored numbers. Flags enums use bits in these numbers to represent multiple options combined.
Why designed this way?
This design allows enums to be efficient and compatible with low-level operations and external systems. Using numeric values means enums can be stored compactly, compared quickly, and used in bitwise operations. Alternatives like storing strings would be slower and use more memory. The ability to customize underlying types and values adds flexibility for different use cases.
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Enum variable β”‚
β”‚  (e.g. Level) β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ stores
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Numeric value β”‚
β”‚  (e.g. 20)    β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ represents
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Named constantβ”‚
β”‚  (e.g. Medium)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Myth Busters - 4 Common Misconceptions
Quick: Does casting any number to an enum always give a named constant? Commit yes or no.
Common Belief:Casting a number to an enum always results in a valid named constant.
Tap to reveal reality
Reality:Casting a number not defined in the enum creates an enum variable with that number but no matching name.
Why it matters:This can cause confusion or bugs when code assumes all enum values have names, leading to unexpected behavior or errors.
Quick: Are enum underlying values always sequential starting at zero? Commit yes or no.
Common Belief:Enum values always start at zero and increase by one automatically.
Tap to reveal reality
Reality:Enum values can be assigned any integer, including non-sequential and negative numbers.
Why it matters:Assuming sequential values can cause logic errors, especially when interfacing with external systems or protocols.
Quick: In Flags enums, do combined values have unique names? Commit yes or no.
Common Belief:Every possible combination of flags has a named constant in the enum.
Tap to reveal reality
Reality:Only individual flags have names; combinations are numeric values without specific names unless explicitly defined.
Why it matters:Misunderstanding this leads to incorrect assumptions about enum values and can cause bugs in flag checks.
Quick: Is the underlying type of enums always int? Commit yes or no.
Common Belief:Enums always use int as their underlying numeric type.
Tap to reveal reality
Reality:Enums can use other integral types like byte, short, long, etc., as specified by the programmer.
Why it matters:Ignoring this can cause data size or compatibility issues, especially when working with external data or memory-sensitive applications.
Expert Zone
1
Enums with custom underlying types affect memory layout and interoperability with unmanaged code, which is critical in performance-sensitive or interop scenarios.
2
Flags enums rely on bitwise operations, but combining flags without checking can produce values that don't correspond to any named constant, requiring careful validation.
3
Casting numeric values to enums bypasses compile-time checks, so runtime validation is essential to avoid invalid enum states.
When NOT to use
Avoid using enums with underlying numeric values when you need extensible sets of values or when values are not fixed, such as user-generated categories. In those cases, use classes, dictionaries, or databases. Also, avoid using enums for complex data that require behavior or multiple properties.
Production Patterns
In production, enums with underlying numeric values are used for configuration flags, protocol message types, error codes, and state machines. Flags enums efficiently represent combinations of options. Developers often use extension methods to add behavior to enums and validation methods to ensure numeric values map to valid enum members.
Connections
Bitwise operations
Builds-on
Understanding underlying numeric values in enums is essential to mastering bitwise operations, especially for Flags enums where bits represent options.
Database primary keys
Analogy
Just like underlying numeric values uniquely identify enum members, primary keys uniquely identify database records, showing a shared pattern of mapping names to numbers.
Digital electronics
Same pattern
The way enums use numeric values and bits mirrors how digital circuits represent states and signals with binary numbers, linking programming to hardware concepts.
Common Pitfalls
#1Assuming casting any number to an enum gives a valid named constant.
Wrong approach:Level lvl = (Level)99; // 99 is not defined in Level enum
Correct approach:if (Enum.IsDefined(typeof(Level), 99)) { Level lvl = (Level)99; } else { // handle invalid value }
Root cause:Misunderstanding that enums can hold any numeric value, not just named constants.
#2Using default enum values without realizing they start at zero.
Wrong approach:enum Status { Ready, Running, Stopped } // Assuming Ready = 1, Running = 2, Stopped = 3
Correct approach:enum Status { Ready = 1, Running = 2, Stopped = 3 }
Root cause:Not knowing C# enums start numbering at zero unless specified.
#3Combining Flags enum values without using bitwise OR.
Wrong approach:Permissions p = Permissions.Read + Permissions.Write; // Using + instead of |
Correct approach:Permissions p = Permissions.Read | Permissions.Write;
Root cause:Confusing arithmetic addition with bitwise operations for flag combinations.
Key Takeaways
Enums in C# represent named constants as underlying numeric values, usually integers, which the computer uses internally.
You can customize these numeric values and the type used to store them, giving flexibility for different needs.
Casting between enums and numbers allows you to convert names to values and back, but casting numbers to enums can produce unnamed values.
Flags enums use powers of two as underlying values to represent combinations of options efficiently with bitwise operations.
Understanding underlying numeric values is essential for debugging, interoperability, and writing clear, efficient code with enums.