Join Gerry O'Brien for an in-depth discussion in this video Understanding the C# data types, part of Learning C# (2014).
All programming languages have language elements. The language elements are the components of the language that you work with to create your code. C# has specific language elements that we'll focus on and in this case we'll talk about the data types. When we start storing information within our program, we have to be able to store that data in some form in the memory of the computer. And C# provides the data types for that. As we work with information in everyday life, it comes in the form of letters, numbers, words, what have you.
C# provides all of these built-in data types, that allow us to store that information in our computer programs. The language has what are referred to as built-in types, or sometimes called intrinsic types. They're also referred to as a simple data type. And the reason that they're considered a simple data type is because they store the information directly in the data type itself, and there's no complexity involved in what the data type looks like. C# has support for numeric types, which allow us to store, as you might expect, numbers.
These can be in the forms of integers, which are typically whole numbers that don't have decimal places. They can be floating point numbers, which have decimal places. We might also store character types. These could be single letters, they could be words, sentences, or phrases. And then there are other types, in this case, one that's known as a boolean type. And a boolean type is one that simply evaluates to either a true or a false value. C# also has support for something known as custom types, and these are considered to be complex types because they really contain more than just a simple data type.
These allow you to create things such as structures or perhaps classes. These two types allow you to encapsulate attributes and functionality within them. Hence the name complex. C# also has support for interfaces. Interfaces are kind of like classes in that they allow you to specify how something might work in terms of functionality. But leave the implementation details for a little bit later down the road in your programming. Another complex type can be considered an enumeration, and C# has full support for enumerations as well.
C# is based on what is known as the common type system. Common Type System is part of the .net framework and all CLS, or common language specification, compliant languages conform to the common type system. What this means is that as we work with data types in our program each one is either a value type or a reference type. And there are specific differences between the two in how the compiler reacts with them, how you react with them and how you write your code to support them.
The common type system supports inheritance within the .net framework. This means that you have the ability to create parent classes and child classes. A parent class is also known as a base class. And a child class could also be considered a sub class. When you create a sub class or a child of a parent class, you inherit the functionality from the parent class in your sub class. All of the value types in C# and within the common type system will derive from something known as the system.value type.
We'll take a look at the different types in C# here in a moment and you see examples of what these different value types are. All of our reference types, including all of our value types, ultimately derive from something known as system.object. This is the highest class in the .net framework that all objects derive from. Taking a look at value types a little bit more, we mentioned that value types are the same as the built-in types. A structure however, even though it's a complex data type, is also considered to be a value type, as are enumerations.
Value types get stored on the stack and if you're not familiar with the term stack within computer memory. It's a logical separation of the memory in the computer where we store information for the program execution. If you think about how a program executes, the computer works with memory addresses. And within these memory addresses we can have instruction pointers, and we can have data. Any time we have data and instruction pointers that get pulled from memory, they get stored on the stack, so that the operating system can keep track of where the execution needs to either come back to or continue on from a certain point.
Value types are also passed by value, which basically means that we're passing in a copy of the data. Not the actual data itself. So, we can manipulate the data without actually changing the original value. If we take a look at reference types a little deeper, we can see that classes are considered to be a reference type, as are interfaces. Reference types are stored on the heap. Again, this is another logical area of memory that the compiler works with when storing information about the data that we have in our application.
We'll see a little bit later on how the stack and the heap differ in how we work with each one of our data types within the application and how our memory resources are managed by the .net framework. It's important to note that reference types are passed by reference. And, again, this is simply how they get their name. When we say it's passed by a reference, we meant that we're passing in a memory address. So, what that basically means is that if we modify a value that is a reference type, we are modifying the original value itself.
Because we are looking directly into the memory address for that type. Lets see an example of some of these as we step out the Visual Studio and then we can go to the process of looking at some of these data types and how they're used within C#. So, here we have Visual Studio up and running, and within Visual Studio, we have a C# console application. This one we have simply called LanguageElement_CS. Within all C# console applications, our main entry point for the code execution is a method called "Main." Main sits within our program class.
Again, this is common across all C# console applications. We talked about the different types of data that we have available in the application itself and within C#. We have support for built in numeric types, and as you can see we some numeric types listed here, sbyte will simple stands for a signed byte, which is an integer, we have a byte which will store a byte of information. Unsigned short, short, integer, and unsigned integer, a long value, unsigned long, etc.
As you can see, the values that are provided and supplied, for the most part, are the maximum values that those data types can support. In other words, we can't go any higher than 65,535 for an unsigned short value. Notice that a signed short value is actually half that. And the reason being is because we need to borrow some bits from the data type to actually represent the negative or positive indicator. We also had support for character data types. We have one called char, which represents a single character.
Now, it doesn't have to be a letter, it can be a number, it can be a special character as well. But it's a single character representation. We also have support for a string, which as you might suspect is actually a string of characters. Internally C# handles this as a specific class or a different type. And then we mentioned boolean types. So, we have bool is the keyword to represent a boolean type. And then we have two possible values. Either true or false. Just to see how these play out, we have a little bit of code here that is currently commented.
Let's uncomment this code so that we can execute it, and we can see what this application will actually output to the console window itself. And C# is complaining a little bit because I'm missing a common character. There we go. So, if I hit Ctrl+F5, C# will compile this code and it will output the information to the screen. Now, in command window, let me go ahead and make some changes to our properties here. We can change the font size a little bit larger here. So, as you can see in our console window we've output some of the values.
A byte which we said in our code was actually a byte value. So, we've declared a byte value here called a byte. And, it output the value of 255. It output the .net framework type, in this case system.byte. It told us the size of, which in this case is one byte. So, that means we are dealing with 8 bits to represent this, one byte. And the maximum value that it is capable of storing is 255. So, we didn't output all of them but you can see examples of some of the built-in intrinsic data types that we specified here, a decimal value we have a double and we have a float.
Now, when I said that I pressed the control F5 in this application,. Ctrl+F5 in a console application allows the window to remain open for us to actually see some of the output results. Without having break points and our debugging of our application. Or without having some other form to hold that application in place. It will simply start out, execute, and then terminate assuming there were no errors. So, Ctrl+F5 is a great way of leaving your console window up and running as you go through the process of looking at how your application output is displayed.
So again, this is very quick and simple. We've taken a look in this example at some of the built-in data types within C#, showing an example of how we can declare them within Visual Studio and output the values. And we've seen an example of the maximum values that they can support. We've seen an example of how we can output those in a console application. We'll take a look at some of the other data types a little bit later on. Such as the numerations, and the structures, and the classes, but for now these are simply the built in data types in C#.
- Installing C#
- Working with loops
- Controlling program flow
- Using variables
- Building functions
- Creating and instantiating classes
- Catching errors
- Managing resources with the garbage collector
- Building collections