What Is a Generic?


To best illustrate what a generic is, and why they are so useful, recall the collection classes from the last chapter. You saw how basic collections could be contained in classes such as ArrayList, but that such collections suffered from being untyped, so you needed to cast object items into whatever type of objects you had actually stored in the collection. Since anything that inherits from System.Object (that is, practically anything) can be stored in an ArrayList, you needed to be careful. Assuming that certain types were all that was contained in the collection could lead to exceptions being thrown, and code logic to break down. You saw techniques that can help you to deal with this, including the code required to check the type of an object. However, you discovered that a much better solution is to use a strongly typed collection class to start off with. By deriving from CollectionBase and proving your own methods for adding, removing, and otherwise accessing members of the collection, you saw how it was possible to restrict collection members to those derived from a certain base type or supporting a certain interface.

And this is where you run up against a problem. Every time you create a new class that needs to be held in a collection, you must do one of the following:

  • Use a collection class you've already made that can contain items of the new type.

  • Create a new collection class that can hold items of the new type, implementing all the required methods.

Typically, with a new type you'll need extra functionality, so more often that not you'll need a new collection class anyway. So, making collection classes may take up a fair amount of your time!

Generic classes, on the other hand, make things a lot simpler. A generic class is one that is built around whatever type, or types, you supply during instantiation, enabling you to strongly type an object with hardly any effort at all. In the context of collections, creating a "collection of type T objects" is as simple as saying it out loud — and achievable in a single line of code. Instead of code such as

CollectionClass col = new CollectionClass(); col.Add(new ItemClass());

you can use:

 CollectionClass<ItemClass> col = new CollectionClass<ItemClass>(); col.Add(new ItemClass());

The angle bracket syntax is the way you pass variable types to generic types. In the preceding code, read CollectionClass<ItemClass> as CollectionClass of ItemClass. You will, of course, examine this syntax in more detail later in the chapter.

There's more to the subject of generics that just collections, but they are particularly suited to this area, as you will see later in the chapter when you look at the System.Collections.Generic namespace. By creating a generic class, you can generate methods that have a signature that can be strongly typed to any type you wish, even catering for the fact that a type may be a value or reference type, and deal with individual cases as they occur. You can even allow only a subset of types to be used, by restricting the types used to instantiate a generic class to those that support a given interface or are derived from a certain type. And you're not restricted to generic classes — you can create generic interfaces, generic methods (which can be defined on nongeneric classes), even generic delegates.

All this adds a great deal of flexibility to your code, and judicious use of generics can cut hours off development time.

One question you may be asking is how this is all possible. Usually, when you create a class it is compiled into a type that you can then use in your code. You might think that when you create a generic class it would have to be compiled into a plethora of types, so that you could instantiate it. Fortunately, this is not the case — and given the infinite amount of classes possible in .NET that's just as well. Behind the scenes, the .NET runtime allows generic classes to be dynamically generated as and when you need them. A given generic class A of B won't even exist until you ask for it by instantiating it.

Note

For those of you who are familiar with C++, or are just interested, this is one difference between C++ templates and C# generic classes. In C++ the compiler would detect where you had used a specific type of template, for example A of B, and compile the code necessary to create this type. In C# everything happens at runtime.

To summarize, generics enable you to create flexible types that process objects of one or more specific type, where these types are determined when you instantiate or otherwise use the generic. Now it's time to see them in action.




Beginning Visual C# 2005
Beginning Visual C#supAND#174;/sup 2005
ISBN: B000N7ETVG
EAN: N/A
Year: 2005
Pages: 278

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net