Microsoft & .NET.NETWhat Are C# Generics?

What Are C# Generics?

What Are C# Generics?

Generics are one of the new features that Microsoft has proposed be added to the C# language. While not a part of the current C# specifications as defined by ECMA or ISO, they could be in the future.

Generics are used to help make the code in your software components much more reusable. They are a type of data structure that contains code that remains the same; however, the data type of the parameters can change with each use. Additionally, the usage within the data structure adapts to the different data type of the passed variables. In summary, a generic is a code template that can be applied to use the same code repeatedly. Each time the generic is used, it can be customized for different data types without needing to rewrite any of the internal code.

While generics would be new, the functionality that is provided by them can be obtained in C# today. This functionality is done by using type casts and polymorphism. With generics, however, you can avoid the messy and intensive conversions from reference types to native types. Additionally, you can create routines that are much more type-safe.

A generic is defined using a slightly different notation. The following is the basic code for a generic named Compare that can compare two items of the same type and return the larger or smaller value, depending on which method is called:

public class Compare<ItemType, ItemType>{   public ItemType Larger(ItemType data, ItemType data2)   {      // logic...   }   public ItemType Smaller(ItemType data, ItemType data2)   {      // logic...   }}

This generic could be used with any data type, ranging from basic data types such as integers to complex classes and structures. When you use the generic, you identify what data type you are using with it. For example, to use an integer with the previous Compare generic, you would enter code similar to the following:

Compare<int, int> compare = new Compare<int, int>;int MyInt = compare.Larger(3, 5);

You could use the type with other types as well. One thing to be aware of is that a declared generic, such Compare in the previous example, is strongly typed. This means that, if you pass a different data type than an integer to compare.Larger, the compiler will display an error. If you wanted to use a different data type, you would need to declare another instance of the generic:

Compare<float, float> f_compare = new Compare<float, float >;float MyFloat = f_compare.Larger(1.23f, 4.32f);

Because you can use this with different types, you don’t need to change the original generic code.

The example here is a simplification of what can be done with generics. You will find that, to truly create a generic type that can be used with any data type as a parameter, you will need to ensure that a number of requirements are met. One way to do this—the appropriate way—is with a constraint. A constraint is a class or interface that must be included as a part of the type used for the parameter. For example, in the previous Compare class, to make sure that any data type will work as a parameter when declaring the delegate, you can force the data types to have implemented the IComparable interface from the .NET Framework.

You can add a constraint by including it after the generic class declaration. You indicate a constraint by using the proposed new C# keyword where:

public class Compare<ItemType, ItemType>          where ItemType : IComparable{   public ItemType Larger(ItemType data, ItemType data2)   {      // logic...   }   public ItemType Smaller(ItemType data, ItemType data2)   {      // logic...   }}

About the Author

Bradley Jones is the Executive Editor for Earthweb’s Software Development channel, which includes sites such as, Codeguru, and Gamelan. He is also the author of the book Sams Teach Yourself the C# Language in 21 Days.

# # #

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories