What Are C# Generics?

Environment: .NET, C# (future)

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 Developer.com, Codeguru, and Gamelan. He is also the author of the book Sams Teach Yourself the C# Language in 21 Days.

# # #



About the Author

Bradley Jones

Bradley Jones, in addition to managing CodeGuru, Brad! oversees the Developer.com Newtwork of sites including Codeguru, Developer.com, DevX, VBForums, and over a dozen more with a focus on software development and database technologies. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days, Web 2.0 Heroes, and Windows Live Essentials and Services.
Google+ Profile | Linked-In Profile | Facebook Page

Comments

  • Perfect Language

    Posted by Legacy on 06/30/2003 12:00am

    Originally posted by: Ratmil

    C# is something like the perfect language. It takes the best of all the other languages. I wonder why generics wasn't included from the beginning. There's one more feature it would be great for C# to have. It is the ability to pass a piece of source code as parameter to a function. This was a smalltalk's feature (that's how I remember it). Something like passing a pointer to a function but defining the function code inline.
    
    

    It could be like this:

    // CODEPIECE would be a piece of code that takes
    // an integer as parameter

    // This function take a piece of code as parameter

    void function f(CODEPIECE C){
    for(int i = 0; i < 10; i++)
    C.Call(i);
    }

    // And you could call this function like this

    void main{
    f(//Paramater is a piece of source code
    {
    //Do something with an integer
    Print(i);
    }
    );
    }

    Or maybe you could create a thread like this:

    void somefunction(){
    Init();
    CreateThread(
    { // Thread body
    while(true){
    Print("Hello\n");
    }
    }
    );
    // Thread has been created
    // with unix's fork syntax
    }


    This could have been used to implement the "forall", but that's already in C#.

    • Nullable Data Types

      Posted by Brad Jones on 08/19/2005 03:10pm

      Nullable data types have been added to the C# 
      language as well.
      
      This means that if your datatype is 'nullable', 
      you could assign a null to an int? value. 
      
      Using the null coalescing operator (??), you could
      create logic that would let you clear out nullable
      values as well. 
      
      http://www.codeguru.com/Csharp/.NET/net_data/datagrid/article.php/c10393/

      Reply
    • You can assign zero to a reference by writing...

      Posted by Alok Govil on 08/18/2005 11:58pm

      reference = null; Seems like I am missing something here.

      Reply
    • Why would you not want to use delegates for this?

      Posted by Alok Govil on 08/18/2005 11:44pm

      delegate void Yourdelegate (int i);
      void yourdelegate (int i)
      {
        //Do something with an integer
        Print(i);
      }
      
      void main ()
      {
         f (new Yourdelegate (this.yourdelegate));
      }

      Reply
    • Why would you not want to use delegates for this?

      Posted by Alok Govil on 08/18/2005 11:43pm

      delegate void Yourdelegate (int i);
      void yourdelegate (int i)
      {
        //Do something with an integer
        Print(i);
      }
      
      void main ()
      {
         f (new Yourdelegate (this.yourdelegate));
      }

      Reply
    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds