() 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 class Employee : IComparable<Employee> {

 public string ID { get; set; }

 public string Name { get; set; }

 public int CompareTo(Employee obj) {

  return this.ID.CompareTo(obj.ID);

 }

}

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.');

Specifying Multiple Constraints

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:

public class MyStack<T> where T : Employee, IComparable<T> {

 //...

}

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);

Multiple Type Parameter

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

Вы читаете C# 2008 Programmer's Reference
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату