Learn the predefined types offered by C# and the different operations that you can perform using them. You then learn about value and reference types. After that, you see nullable types and learn about type conversion.

In Hour 1, “The .NET Framework and C#,” you were introduced to the fundamentals of the .NET Framework and C#, including the framework class library, the common language runtime, and the idea of automatic memory management. You briefly learned about namespaces and types and then moved on to statements, expressions, variables, constants, identifiers, and keywords. From those humble beginnings, you then built a simple C# application and learned about debugging in Hour 2, “Introducing Visual Studio.”

Building on what you have already learned, this hour introduces you to the predefined types offered by C# and the different operations that you can perform using them. You then learn about value and reference types. After that, you see nullable types and learn about type conversion.

At the end of this hour, you should have a thorough understanding of the C# types, including the difference between value, reference, and nullable types. You will also have written some more advanced applications that can store and manipulate simple data.

An Overview of Types

C# is both a type-safe and statically typed language. Being statically typed requires you to inform the compiler of the data type for any variable you create. In return, the compiler guarantees that you can only store a compatible data type in that variable, making it type safe. This combination helps prevent common programming errors, leading to a more stable and secure application.

Types are divided into three main categories:

Value types

Reference types

Type parameters

Go To

HOUR 12, “UNDERSTANDING GENERICS,” for more information on type parameters.

Tip: Pointers

There is actually a fourth category of type, called a pointer, which is not part of the core C# language. A pointer type contains the actual location (called an address) of an item in memory. Pointers also allow arithmetic operations as if the value were a number. Although pointers are powerful, they can also be difficult to use correctly and safely.

There are times, however, when using pointers might be required. Fortunately, almost all those times are situations that are more advanced and not something that we need to worry about on a regular basis. Some of those situations can include directly interacting with the underlying operating system or implementing an extremely time-critical algorithm.

To allow the flexibility (and danger) of pointers, C# enables you to write unsafe code in which it is possible to create and operate on pointers. When using unsafe code and pointers, be aware that the garbage collector does not track pointers, so you must handle the memory allocation and deletion yourself. In a way, it’s like writing C code in a C# program.

By disallowing pointer types except in explicit unsafe code blocks, C# can eliminate an entire category of common errors, making it a much safer language.

Put simply, a value type is completely self-contained and copied “by value.” This means that variables of a value type directly contain their data, and it is not possible for operations on one to affect the other. Value types are further categorized into structures, enumerated types, and nullable types.

A reference type contains a reference to the actual data, meaning it is possible for two variables to reference the same object, allowing the possibility that operations on one will affect the other. Reference types are further categorized into classes, arrays, interfaces, and delegates.

Note: Unified Type System

Despite this division between types, C# has a unified type system, enabling the value of any nonpointer type to be treated as an object. This gives value types the benefits a reference type has without introducing unnecessary overhead and makes it possible to call object methods on any value, even predefined value types.