Understanding C#: Explore types using the Type class and GetType()

By Andrew Stellman
August 5, 2010

One of the most powerful aspects of the C# programming language is its rich type system. But until you've got some experience building programs, it's difficult to appreciate it--in fact, it can be a little baffling at first. But we want to give you at least a taste of how types work in C# and .NET. This tutorial helps get you started exploring the type system. In it, you'll create a console application that gives you an introduction to some of the tools you have at your disposal to work with types.

Head First C# Cover

A few months ago, one of our Head First C# readers sent me an e-mail asking about types. I thought it was actually a really good question:

I recently purchased Head First C# and am enjoying it immensely. But I have this problem, I see the word 'Type' in your book and others, but I am yet to find a definitive definition as to just what a "Type" is. What comprises a type? What are the elements --pieces--parts-- of a "Type ? How does one originate a Type? Is a 'Data Type' the only form of a Type?

I sent a response encouraging the reader to keep reading in the book, because we do answer a lot of those questions: what a type is, the built-in types for C# and .NET, how you use those types in a program, how you convert them, and how you can use classes and structs to define new types

I also promised that I would write a blog post to give some additional hints about types. The best way I know of to learn about a programming topic like this is to start experimenting. And a good place to start experimenting with types in C# is to use the Type class and the GetType() method

So here's a quick tutorial to help you start exploring the C# and .NET type system. It's just a starting point, but it should answer the biggest questions about C# types, type names, nested classes, and more -- all in about 20 minutes.

Setting up the project

Start out by creating a new Console Application project in Visual Studio. It should create a new Program.cs for you—that's where you'll be adding code. The only other thing you'll need is the Guy class. If you've done many of my other C# tutorials and blog posts, you'll recognize it as my general-purpose utility class.

So the next step is to add the Guy class to your project. You can find the source to the Guy class here, and if you want you can follow the same instructions in the Understanding Namespaces and Assemblies tutorial.

One of the things we only mentioned briefly in Head First C# was the concept of a nested class. When you're exploring types, it's good to have a reminder that you can nest classes inside of each other. Edit the Program.cs file to add a nested called NestedClass to your Program class. The NestedClass class contains its own nested class, called DoubleNestedClass. Here's the code—add it to the top of Program.cs:

class Program
{
     class NestedClass
     {
          public class DoubleNestedClass
          {
               // Nested class contents ...
          }
      }
 
     static void Main(string[] args) 
     {
     }
}
Explore types using the Type class and GetType()

For the rest of the tutorial, you'll be adding lines to the Main() method in Program.cs. After you add each set of lines, I recommend running the program outside of the debugger by pressing Ctrl-F5 in the IDE. That causes Visual Studio to run the program and then display a "Press any key to continue . . ." prompt, so the window doesn't disappear. Alternately, you can add a Console.ReadKey(); line at the end of the program. We'll throw one in at the bottom of the program to keep the window open if you run it in the debugger.

Let's get started by creating a Type object using the typeof keyword. You can use the typeof keyword to turn a type (like Guy, int, or DateTime) into a Type object. Then you can find out its full name and base type (and if it didn't inherit from anything, its base type is System.Object).

Add the following code to the top of the Main() method:

Type guyType = typeof(Guy); 
Console.WriteLine("{0} extends {1}",
    guyType.FullName,
    guyType.BaseType.FullName); 

You should see the following output:

TypeExamples.Guy extends System.Object

When I created my program, I named my program "TypeExamples", so when Visual Studio created the project it added a namespace called TypeExamples. That's why the full name of the Guy type is TypeExamples.Guy. If you used a different namespace, your output will show that instead.

Next, see what happens when you get the type of a nested class or a generic type:

Type nestedClassType = typeof(NestedClass.DoubleNestedClass);
Console.WriteLine(nestedClassType.FullName); 

List<Guy> guyList = new List<Guy>();
Console.WriteLine(guyList.GetType().Name);

Nested classes are represented using a plus sign. When you get the type of a generic, its name is the type name followed by a backward quote and the number of its generic parameters. Here's what the output from these lines should look like:

TypeExamples.Program+NestedClass+DoubleNestedClass
List`1

The GetType() method returns a Type object. It's a member of System.Object, so every object has a GetType() method. The System.Type class has a FullName property, which we used in the first part of this program. You can use GetType() or typeof, both will return a Type object:

Dictionary<string, Guy> guyDictionary = new Dictionary<string, Guy>();
Console.WriteLine(guyDictionary.GetType().Name);

Type t = typeof(Program); 
Console.WriteLine(t.FullName);

The output from those lines looks like this:

Dictionary`2
TypeExamples.Program

Some keywords that you're familiar with are aliases. float is an alias for System.Single and int is an alias for System.Int32. They're both structs (which you can learn all about in Chapter 14 of Head First C#):

Type intType = typeof(int); 
Type int32Type = typeof(Int32); 
Console.WriteLine("{0} - {1}", intType.FullName, int32Type.FullName); 

The output from those lines looks like this:

System.Int32 - System.Int32

Numeric value types and DateTime have MinValue and MaxValue properties that return the lowest and highest valid value. And literals have types, too! You can use GetType() to get those types:

Console.WriteLine("{0} {1}", float.MinValue, float.MaxValue); 
Console.WriteLine("{0} {1}", int.MinValue, int.MaxValue); 
Console.WriteLine("{0} {1}", DateTime.MinValue, DateTime.MaxValue);
Console.WriteLine(12345.GetType().FullName);

The output from those lines looks like this:

-3.402823E+38 3.402823E+38
-2147483648 2147483647
1/1/0001 12:00:00 AM 12/31/9999 11:59:59 PM
System.Int32

Putting it all together Here's the whole Program class, in case you want to paste the whole thing into a project. (Don't forget that you also need to add the Guy class for this code to work.)
class Program
{
     class NestedClass
     {
          public class DoubleNestedClass
          {
               // Nested class contents ...
          }
     }
 
     static void Main(string[] args)
     {
          Type guyType = typeof(Guy);
          Console.WriteLine("{0} extends {1}",
              guyType.FullName,
              guyType.BaseType.FullName);
          // output: TypeExamples.Guy extends System.Object
  
          Type nestedClassType = typeof(NestedClass.DoubleNestedClass);
          Console.WriteLine(nestedClassType.FullName);
          // output: TypeExamples.Program+NestedClass+DoubleNestedClass
  
          List<Guy> guyList = new List<Guy>();
          Console.WriteLine(guyList.GetType().Name);
          // output: List`1
  
          Dictionary<string, Guy> guyDictionary = new Dictionary<string, Guy>();
          Console.WriteLine(guyDictionary.GetType().Name);
          // output: Dictionary`2
  
          Type t = typeof(Program);
          Console.WriteLine(t.FullName);
          // output: TypeExamples.Program
  
          Type intType = typeof(int);
          Type int32Type = typeof(Int32);
          Console.WriteLine("{0} - {1}", intType.FullName, int32Type.FullName);
          // System.Int32 - System.Int32
  
          Console.WriteLine("{0} {1}", float.MinValue, float.MaxValue);
          // output:-3.402823E+38 3.402823E+38
  
          Console.WriteLine("{0} {1}", int.MinValue, int.MaxValue);
          // output:-2147483648 2147483647
  
          Console.WriteLine("{0} {1}", DateTime.MinValue, DateTime.MaxValue);
          // output: 1/1/0001 12:00:00 AM 12/31/9999 11:59:59 PM
  
          Console.WriteLine(12345.GetType().FullName);
          // output: System.Int32
  
          Console.ReadKey();
     }
}

There's so much more to learn about types! This tutorial should definitely get you started. If you want to learn more about types, you can read more about them here: Types (C# Programming Guide) .

Andrew Stellman is the author of Head First C# and other books from O'Reilly. You can read more from Andrew at Building Better Software.


You might also be interested in:

News Topics

Recommended for You

Got a Question?