C# is an Object-oriented programming language. C# comes with simplicity, expressiveness and great performance to meet the programmer productivity.
Introduction
So far, we have studied
Generic types in
C#. Let's see generic methods, interfaces and constraints of
C# in this chapter.
Background
The main objective of this article is to learn generic methods
, generic interfaces
and generic constraints
in C# programming.
Generic Methods
Generic methods have the type parameters which helps to parameterize the types used in a method. In other words, we can provide a single implementation call it with different types.
Generic method should be like,
static void MyMethod<T>(...., ....)
{
.........;
........;
}
We already know that generics allow us to write a method or a
class which is able to work with any data type. Let's have a simple example of generic method,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Example
{
class Program
{
public class MyClass
{
static void Change<T>(ref T x, ref T y) // generic method
{
T dummy = x; // swapping
x = y; // functionality
y = dummy; // ..........
}
public static void XChange()
{
int i = 3, j = 6;
Change<int>(ref i, ref j); // swaps the values
Console.WriteLine(i + " & " + j); // prints 6 & 3
}
}
static void Main()
{
MyClass.XChange(); // calls XChange method
}
}
}
In the above code, we have a generic method Change<T> with parameters x
and y
. In that method, we are implementing the swapping functionality.
And we also have a simple method XChange() for swapping integers by calling the generic method Change<T>.
Now in the Main() method, we are just calling the XChange() method which in return calls the generic method Change<T> and prints the following lines in your console.
Generic Interfaces
We can define interfaces for generic collection classes as well as for the generic classes which represents the collection items. This is very helpful in
C# programming to use the generic interfaces such as
IComparable<T> rather than
IComparable to avoid boxing and unboxing operations on value types.
Example:
Lets have an example program that uses generic interface IList<T>,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Example
{
class Program
{
static void Main()
{
char[] vowels = new char[5];
vowels[0] = 'a';
vowels[1] = 'e';
vowels[2] = 'i';
vowels[3] = 'o';
vowels[4] = 'u';
Show(vowels); // Calls Show() method
List<char> cons = new List<char>(); // Generic class
cons.Add('b');
cons.Add('c');
cons.Add('d');
Show(cons); // Calls Show() method
}
static void Show(IList<char> li) // Generic interface IList
{
Console.WriteLine("Total: {0}", li.Count);
foreach (char c in li)
{
Console.WriteLine(c);
}
}
}
}
In the above simple program, we defined an array '
vowels
'. And we declared a generic type '
cons
'. Both are the character (char) arrays.
Now, press Ctrl + F5 to see the following lines in your console,
Generic Constraints
If we require more specific type arguments to a type parameter, constraints can be applied. In other words, constraints are the restrictions which are used to restrict client side code to access the specific type.
'
where
' (
contextual keyword) is the keyword used to specify the constraints. We have six constraints in C# generics. They are,
- where T : class - It is a reference type constraint which can be applied to any class, interface,
delegate
and array type. - where T : struct - It is a value type constraint which can be applied for any value except Nullable.
- where T : interface - It is an interface constraint applied for a type that must be implemented the specified interface. We can also specify multiple interface constraints.
- where T : base class - Base class constraint can be applied to a type argument that must be in or derived from the base class.
- where T : new() - This is known as parameter-less constructor constraint. It can be applied to the type argument which have a public parameter-less constructor. new() constraint should be specified last when the type argument is used together with other constraints.
- where T : U - It is a naked type constraint can be applied to a type argument for T in which it must be or derive from the argument supplied for U.
Constraints can be applied for both methods and type parameters wherever they are defined.
Conclusion
In this article, we have seen generic methods, interfaces and constraints of C#
generics. Hope you understand.
Thanks for reading,
Regards,
Krishna.