()
method:
MyStack<string> stack = new MyStack<string>(3);
stack.Push('A');
stack.Push('B');
stack.Push('C');
if (stack.Find('B')) Console.WriteLine('Contains B');
In this case, the code works because the string
type implements the IComparable
interface. Suppose that you have the following Employee
class definition:
public class Employee {
public string ID { get; set; }
public string Name { get; set; }
}
When you try to use the MyStack
class with the Employee
class, you get an error:
MyStack<Employee> stack = new MyStack<Employee>(3); //---Error---
That's because the Employee
class does not implement the IComparable<T>
interface. To resolve this, simply implement the IComparable<Employee>
interface in the Employee
class and implement the CompareTo()
method:
public string ID { get; set; }
public string Name { get; set; }
}
You can now use the Employee
class with the generic MyStack
class:
MyStack<Employee> stack = new MyStack<Employee>(2);
stack.Push(new Employee() { ID = '123', Name = 'John' });
stack.Push(new Employee() { ID = '456', Name = 'Margaret' });
Employee e1 = new Employee() { ID = '123', Name = 'John' };
if (stack.Find(e1))
Console.WriteLine('Employee found.');
You can specify multiple constraints in a generic type. For example, if you want the MyStack
class to manipulate objects of type Employee
and also implement the IComparable
interface, you can declare the generic type as:
//...
}
Here, you are constraining that the MyStack
class must use types derived from Employee
and they must also implement the IComparable
interface.
The base class constraint must always be specified first, before specifying the interface.
Assuming that you have the following Manager
class deriving from the Employee
class:
public class Manager : Employee, IComparable<Manager> {
public int CompareTo(Manager obj) {
return base.CompareTo(obj);
}
}
The following statement is now valid:
MyStack<Manager> stackM = new MyStack<Manager>(3);
So far you have seen only one type parameter used in a generic type, but you can have multiple type parameters. For example, the following MyDictionary
class uses two generic type parameters — K
and V
:
public class MyDictionary<K, V> {
//...
}
To apply constraints on multiple type parameters, use the where
keyword multiple times:
public class MyDictionary<K, V>
where K : IComparable<K> where V : ICloneable {
//...
}
Generic Interfaces
Generics can also be applied on interfaces. The following example defines the IMyStack
interface:
interface IMyStack<T> where T : IComparable<T> {
void Push(T item);
T Pop();
bool Find(T keyword);
}
A class implementing a generic interface must supply the same type parameter as well as satisfy the constraints imposed by the interface.
The following shows the generic MyStack
class implementing the generic IMyStack
interface:
public class MyStack<T> : IMyStack<T>
where T : IComparable<T> {
//...
}
Figure 9-4 shows the error reported by Visual Studio 2008 if the generic MyStack
class does not provide the constraint imposed by the generic interface.

Figure 9-4
Generic Structs