- Introduction
- Using Generic Collections
- Implementing a Generic Class
- Adding Type Constraints
- Summary
Adding Type Constraints
The final element to discuss is constraints. Constraints are placed on classes or features and use the following syntax:
Where T : constraint_type
For example, anything we'd like to use in a using statement, such as a SqlDataReader, must implement IDisposable. This is because a using statement like this:
using(Form f = new Form()){...}
works just like a try..finally block by always cleaning up the created resource. This works quite simply by the CLR emitting a call to IDisposable.Dispose for the object created in the using statement. For instance, in the fragment a new Form is created, and before the using statement exits Form.Dispose is called.
To place a constraint on a generic class that ensures that the class implements IDisposable, we would add the predicate where T : IDisposable. Applied to our generic list in Listing 4, we would revise Listing 4 as shown in Listing 5.
Listing 5 Adding a constraint to the generic class to ensure that all values for T for our List<T> implement IDisposable.
using System; using System.Collections; using System.Text; namespace Generics { public class List<T> : CollectionBase where t : IDisposable { public List(){ } public T this[int index] { get { return (T)List[index]; } set { List[index] = value; } } public int Add(T value) { return List.Add(value); } } }
Values for the where predicate can be classes, interfaces, structures, classes that implement a parameter-less public constructor, or classes that have a specific base class. Check out the help documentation for specifics.