C# Generics Tutorial with Examples
1. Generics Class
The example below defines a generics class. KeyValue is a generics class that contains pairs of key and value.
KeyValue.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
public class KeyValue<K, V>
{
private K key;
private V value;
public KeyValue(K key, V value)
{
this.key = key;
this.value = value;
}
public K GetKey()
{
return key;
}
public void SetKey(K key)
{
this.key = key;
}
public V GetValue()
{
return value;
}
public void SetValue(V value)
{
this.value = value;
}
}
}
K, V in KeyValue <K, V> class is called generics parameters which is a certain type of data. When using this class, you must determine the specific parameter.
Take the example of using KeyValue class
KeyValueDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
public class KeyValueDemo
{
public static void Main(string[] args)
{
// Create KeyValue object.
// int: Phone Number (K = int)
// string: Name (V = string)
KeyValue<int, string> entry = new KeyValue<int, string>(12000111, "Tom");
// C# understands that the return type is a int
int phone = entry.GetKey();
// C# understands that the return type is a string
string name = entry.GetValue();
Console.WriteLine("Phone = " + phone + " / name = " + name);
Console.Read();
}
}
}
Running Example:
Phone = 12000111 / name = Tom
2. Inheritance Generics class
A class extended from a generics class can specify parameter type for generics, retain generics parameters or add generics parameters .
Example 1:
PhoneNameEntry.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
// This class extends KeyValue<K,V>
// And specify the type for the K & V
// K = int (Phone Number)
// V = string (Name)
public class PhoneNameEntry : KeyValue<int, string>
{
public PhoneNameEntry(int key, string value)
: base(key, value)
{
}
}
}
Example use PhoneNameEntry:
PhoneNameEntryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
public class PhoneNameEntryDemo
{
public static void Main(string[] args)
{
PhoneNameEntry entry = new PhoneNameEntry(12000111, "Tom");
// C# understands that the return type is int.
int phone = entry.GetKey();
// C# understands that the return type is string.
string name = entry.GetValue();
Console.WriteLine("Phone = " + phone + " / name = " + name);
Console.Read();
}
}
}
Example 2:
StringAndValueEntry.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
// This class extends KeyValue<K,V>
// Specify the parameter K is string.
public class StringAndValueEntry<V> : KeyValue<string, V>
{
public StringAndValueEntry(string key, V value)
: base(key, value)
{
}
}
}
Example use StringAndValueEntry class:
StringAndValueEntryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
public class StringAndValueEntryDemo
{
public static void main(String[] args)
{
// (Emp Number, Employee Name)
// V = string (Employee Name)
StringAndValueEntry<String> entry = new StringAndValueEntry<String>("E001", "Tom");
String empNumber = entry.GetKey();
String empName = entry.GetValue();
Console.WriteLine("Emp Number = " + empNumber);
Console.WriteLine("Emp Name = " + empName);
Console.Read();
}
}
}
Example 3:
KeyValueInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
// This class extends KeyValue<K,V>.
// It has added a parameter generics I.
public class KeyValueInfo<K, V, I> : KeyValue<K, V>
{
private I info;
public KeyValueInfo(K key, V value)
: base(key, value)
{
}
public KeyValueInfo(K key, V value, I info)
: base(key, value)
{
this.info = info;
}
public I GetInfo()
{
return info;
}
public void GetInfo(I info)
{
this.info = info;
}
}
}
3. Generics Interface
Interface with Generics:
GenericInterface.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
public interface GenericInterface<G>
{
G DoSomething();
}
}
For example, an implementation of the interface:
GenericInterfaceImpl.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
public class GenericInterfaceImpl<G> : GenericInterface<G>
{
private G something;
public G DoSomething()
{
return something;
}
}
}
4. Using Generics with Exception
You can create an Exception with Generics parameters.
MyException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
class MyException<E> : ApplicationException
{
}
}
Using the Generic Exception (Valid):
UsingGenericExceptionValid01.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
class UsingGenericExceptionValid01
{
public void SomeMethod()
{
try
{
// ...
}
// Valid
catch (MyException<string> e)
{
// Do something here.
}
// Valid
catch (MyException<int> e)
{
// Do something here.
}
catch (Exception e)
{
}
}
}
}
Using the Generic Exception (Valid):
UsingGenericExceptionValid02.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
class UsingGenericExceptionValid02<K>
{
public void SomeMethod()
{
try
{
// ...
}
// Valid
catch (MyException<string> e)
{
// Do something here.
}
// Valid
catch (MyException<K> e)
{
// Do something here.
}
catch (Exception e)
{
}
}
}
}
Using the Generic Exception (Invalid):
UsingGenericExceptionInvalid.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
class UsingGenericExceptionInvalid
{
public void SomeMethod()
{
try
{
// ...
}
// Valid
catch (MyException<string> e)
{
// Do something here.
}
// Invalid (Unknown parameter K) ***********
// catch (MyException<K> e)
// {
// ...
// }
catch (Exception e)
{
}
}
}
}
5. Generic Methods
A method in class or Interface may be generified.
MyUtils.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
public class MyUtils
{
// <K, V>: To say that this method has two parameters K, V
// Method returns K.
public static K GetKey<K, V>(KeyValue<K, V> entry)
{
K key = entry.GetKey();
return key;
}
// <K, V>: To say that this method has two parameters K, V
// Method returns V.
public static V GetValue<K, V>(KeyValue<K, V> entry)
{
V value = entry.GetValue();
return value;
}
// List <E>: The list contains the elements of type E
// This method returns the type E.
public static E GetFirstElement<E>(List<E> list, E defaultValue)
{
if (list == null || list.Count == 0)
{
return defaultValue;
}
E first = list.ElementAt(0);
return first;
}
}
}
For example, using generics method :
MyUtilsDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
public class MyUtilsDemo
{
public static void Main(string[] args)
{
// K = int: Phone
// V = string: Name
KeyValue<int, string> entry1 = new KeyValue<int, String>(12000111, "Tom");
KeyValue<int, string> entry2 = new KeyValue<int, String>(12000112, "Jerry");
// (K = int).
int phone = MyUtils.GetKey(entry1);
Console.WriteLine("Phone = " + phone);
// A list containing the element type KeyValue<int, string>.
List<KeyValue<int, string>> list = new List<KeyValue<int, string>>();
// Add element to list
list.Add(entry1);
list.Add(entry2);
KeyValue<int, string> firstEntry = MyUtils.GetFirstElement(list, null);
if (firstEntry != null)
{
Console.WriteLine("Value = " + firstEntry.GetValue());
}
Console.Read();
}
}
}
Running example:
Phone = 12000111
Value = Tom
6. Generic Object Initialization
Sometimes, you want to initialize a Generic object:
public void DoSomething<T>()
{
// Generic Object Initialization
T t = new T(); // Error
}
The cause is T parameter is unlikely that it has constructor T(), so you need to add when T: new() constraints. See the example below:
GenericInitializationExample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
class GenericInitializationExample
{
// Type T must have default constructor.
public void DoSomeThing<T>()
where T : new()
{
T t = new T();
}
// Type K must have default constructor.
// and extends KeyValue<K,string>
public void ToDoSomeThing<K>()
where K: KeyValue<K,string>, new( )
{
K key = new K();
}
public T DoDefault<T>()
{
// Return null if T is reference type
// or return 0 if T is number (int, float,..)
return default(T);
}
}
}
7. Generic Array
In C # you can declare an array of generics:
// Initialize an array.
T[] myArray = new T[10];
GenericArrayExample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
class GenericArrayExample
{
public static T[] FilledArray<T>(T value, int count)
{
T[] ret = new T[count];
for (int i = 0; i < count; i++)
{
ret[i] = value;
}
return ret;
}
public static void Main(string[] args)
{
string value = "Hello";
string[] filledArray = FilledArray<string>(value, 10);
foreach (string s in filledArray)
{
Console.WriteLine(s);
}
}
}
}
C# Programming Tutorials
- Inheritance and polymorphism in C#
- What is needed to get started with C#?
- Quick learning C# for Beginners
- Install Visual Studio 2013 on Windows
- Abstract class and Interface in C#
- Install Visual Studio 2015 on Windows
- Compression and decompression in C#
- C# Multithreading Programming Tutorial with Examples
- C# Delegates and Events Tutorial with Examples
- Install AnkhSVN on Windows
- C# Programming for Team using Visual Studio and SVN
- Install .Net Framework
- Access Modifier in C#
- C# String and StringBuilder Tutorial with Examples
- C# Properties Tutorial with Examples
- C# Enums Tutorial with Examples
- C# Structures Tutorial with Examples
- C# Generics Tutorial with Examples
- C# Exception Handling Tutorial with Examples
- C# Date Time Tutorial with Examples
- Manipulating files and directories in C#
- C# Streams tutorial - binary streams in C#
- C# Regular Expressions Tutorial with Examples
- Connect to SQL Server Database in C#
- Work with SQL Server database in C#
- Connect to MySQL database in C#
- Work with MySQL database in C#
- Connect to Oracle Database in C# without Oracle Client
- Work with Oracle database in C#
Show More