Value Types in the .NET Framework – C#

All elements of the .NET Framework are built upon a handful of core concepts: system types, custom types, interfaces, and events. System types describe the most basic types in the .NET framework, including strings and integers. All other types are built using system types.

Developers can leverage system types to create custom types, which have unique behavior defined by the developer’s custom code. Typically, developers create custom types by extending one of the existing types. To allow types to be extended, the .NET framework provides the concept of interfaces. Interfaces define standard contracts with which derived types must comply.

Programming with the .NET Framework is rarely linear. Applications must respond to user input, listen for incoming network communications, and perform background processing. The .NET Framework provides events and delegates to allow this non-linear structure. Using these concepts, developers can respond to a mouse click (an event) by running a specified method (the delegate).

Most .NET Framework applications perform some text processing, whether validating user input, generating log files, or reading data from a text file. The most efficient way to process text is to use regular expressions. Regular expressions allow developers to isolate specific portions of text with only a few lines of code. Regular expressions can also be used to update text and format text for output.No matter how basic or complex, all .NET Framework development leverages these concepts.

System types come in two varieties: value and reference. This lesson describes value types. Value types are the simplest types in the .NET Framework, consisting primarily of numbers and true/false values (known as Boolean values).

While value and reference types can be used similarly, the .NET runtime stores them differently in memory. If you don’t understand the differences between value and reference types, you could be surprised by the behavior of an object, causing difficult-to-track bugs.

These pages provides an overview of built-in value types, how to use each of them, and how to create custom value types. An understanding of value types is required for building more complex classes based on these types.

These pages will show you how to:

  • List common value types
  • Choose between different numeric types
  • Create enumerations

Declaring value types is straightforward. The following code sample demonstrates declaring four value types and setting their initial value.

int i = 10;
long l = 2000;
decimal d = 10.5M;
bool b = false;

As demonstrated above, the integer (int in C#), long, and decimal classes each store numbers. The Boolean (bool in C#) class stores a value of true or false. Later topics provide a more thorough description of each value class.

Declaring Variables as Nullable

It’s easy to understand that integers, longs, and decimals store numbers, and that Boolean values store true/false values. However, any of these types is also capable of having a value of null, which means that the value has not been assigned.

For example, if you are using an integer to store a student’s test score in the range of 0-100, you might assign the integer a null value to indicate that the student’s test has not yet been graded. Similarly, if you create an array of Boolean values to store a student’s answers to true/false questions, a null value could be used to indicate questions that the student has not yet answered.

Use the Nullable keyword when declaring a variable to make the object nullable. Declaring a value as nullable enables the HasValue and Value members. Use HasValue to detect whether a value has been set, as this code sample demonstrates:

Nullable<bool> b = null; 
if (b.HasValue)
     Console.WriteLine("b is {0}.", b.Value); 

     Console.WriteLine("b is not set.");

Here’s a video demonstrating this:

This table shows the value types built into the .NET Framework, in order from shortest number of bytes to longest number of bytes. For best performance and memory efficiency, use the smallest type that meets your requirements. For example, if you are creating a counter that will only go to 10, you should use the Byte type. If you need a counter that will go to 1000, use the Int16 type.

In common practice, developers use the aliases for the different types. For example, instead of writing System.Int32, most Visual Basic developers use the Integer alias, and most C# developers use the int alias.

Type (C# alias)

Value Range


System.SByte (sbyte)

–128 to 127

1 byte. Use whenever you need to store a value between -128 and 127.

System.Byte (byte)

0 to 255

1 byte. Use whenever you need to store a value between 0 and 255.

System.Int16 (short)

-32768 to 32767

2 bytes. Typically only used for interoperating with COM objects which might require a short. Otherwise, you can use Int32 instead.

System.Int32 (int)

–2147483648 to 2147483647

4 bytes. Use for whole numbers (numbers that do not require a decimal).

System.UInt32 (uint)

0 to 4294967295

4 bytes. Use for positive whole numbers that might be greater than is allowed by Int32.

System.Int64 (long)

9223372036854775808 to 9223372036854775807

8 bytes. Use for large whole numbers.

System.Single (float)

–3.402823E+38 to 3.402823E+38

4 bytes. Use for floating point numbers.

System.Double (double)

–1.79769313486232E+308 to 1.79769313486232E+308

8 bytes. Use for larger or more precise floating point numbers.

System.Decimal (decimal)

–79228162514264337593543950335 to 79228162514264337593543950335

16 bytes. Use for financial and scientific calculations requiring great precision.

The .NET Framework also includes the following non-numeric value types. There are nearly 300 more value types in the .NET Framework, but these and the numeric types are the most frequently used.

Type (C# Alias)



System.Char (char)


Single unicode characters

System.Boolean (bool)


True/False values



Pointer to a memory address

System.DateTime (date)


Times and dates

If you pass an instance of a value type to a method, the .NET Framework creates a copy of the value. Therefore, any changes that the method makes to the value are not available to the calling method.

For example, running the following console application displays the value 2, demonstrating that changes the method makes are not available outside of the method.

static void Main()
    int i = 2;

static void AddTwo(int n)
    n += 2;

If the object i were passed by reference, the application would have displayed 4 because reference types can be updated by methods. The next lesson describes passing values by reference in detail.

A better way to update value types from methods is to use a return value. The following code sample updates the value type using the method’s return value, and displays 4.

static void Main()
    int i = 2;
    i = AddTwo(i);

static int AddTwo(int n)
    return n + 2;

Return to the .NET Framework Fundamentals Table of Contents.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>