다음을 통해 공유


C# Generics

Hello, I am Syam Pinnaka, I am a developer in Infosec tools team. In this blog post lets recap some information about C# Generics.

One of the problems with OOP is “code bloat”. One type of code bloat occurs when a function or a set of methods in a class are overloaded to support many different data types possible as method parameters. One solution to “code bloat” is the ability of one parameter to take on different data types, while at the same time providing just one definition for that parameter. This technique is called generic programming. Generic programming is traditionally supported in C++ with templates. This feature is supported in C# 2.0 as Generics. Generics allow the developer to write a function or class with a place holder data type and use it with many different data types without having to overload the function or class. This “placeholder” data type is filled in by a specific data type at compile time.

This placeholder is represented by a pair of angle brackets (<>), with an identifier placed between the brackets. Lets see an example to understand this better. Lets say we want to write a generic swap function which can work with any data type. Here is how the function will look like.

  
 void swap<T>(ref T val1, ref T val2)
{
    T temp;
    temp = val1;
    val1 = val2;
    val2 = temp;
} 

The placeholder for the data type is placed immediately after the function name. The identifier placed inside the angle brackets is used whenever a generic data type is needed. Each of the parameters is assigned a generic data type, as is the temp variable used to make the swap.

Generics are not limited to function definitions. This concept can be extended to create generic classes. A generic class will contain a genetic data type placeholder after the class name. Anytime the class name is referenced in the definition, the type placeholder can be provided. Lets see the class definition of a generic class.

 

 public class Node<T> {
T data;
Node<T> link;
    public Node(T data, Node<T> link)
    {
        this.data = data;
        this.link = link;
    }
}

 

this class can be used like this.

 

Node<string> node1 = new Node<string>(“Syam”, null);

Node<string> node2 = new Node<string>(“Gaurav”, node1);

Node<string> node3 = new Node<string>(“Anil”, node2);

Node<string> node4 = new Node<string>(“Anil”, node3);

 

This concept can also be extended to use more than one generic placeholder in a class/method definition. Meaning that we can use more than one generic  data type in a single method/class definition. Lets say we have a need to add an item to a generic list by taking (an int) key, value but only after checking that key, val combination is not already present in the list. To accomplish this, we can use a generic method like below.

         public static bool CheckAndAddItemToList<T1, T2>(ref List<T1> list, T1 item, T2 key)
        {
            var foundItem = list.Find(p => p.Equals(item)); //If found, foundItem will contain item.      
            T1 FoundMember = (T1)foundItem;

            if ((FoundMember != null) && (FoundMember.Equals(item)))
                return false;

            list[Int16.Parse( key.ToString()) ] = item;
            return true;
        }

 

C# provides a library of generic data structures ready to use. These data structures can be found in the System.Collection.Generics namespace. These classes have the same functionality as the no generic data structure class. Some of the generic classes are System.Collections.Generic.List<T>, System.Collections.Generic.LinkedList<T>, System.Collections.Generic.Queue<T>, System.Collections.Generic.SortedDictionary<TKey,TValue>, System.Collections.Generic.SortedList<TKey,TValue> and System.Collections.Generic.Stack<T>.

I have found these classes very useful whenever there is  a need to support more than one data type and recommend them to avoid “Code Bloat” and at the same time reap the full benefits of .net framework. Happy (C#) coding!