Within the body of a generic class or method, the compiler only knows that the placeholder represents something derived from object. But to really compose types to create behavior, the generic needs to interact with its constituent types. You can give it the information it needs by adding constraints to the type placeholders.

A constraint limits the types that can be used with the generic. You can say that a generic can only be used with types that implement an interface, extend a base class, or have a certain constructor. In exchange for this limitation, the generic gets access to methods of that interface, base class, or constructor.

In C#, you use the "where" keyword after the class or method header. The placeholder is followed by a colon and a list of constraints. A constraint is an interface that the placeholder must implement, a base class it must extend, or a constructor that it must have. Even though it looks like the colon represents inheritance, don't get confused. This syntax is used for all constraints, not just interfaces and base classes.

In VB, you use the "As" keyword immediately after the placeholder declaration. If you have more than one constraint, you enclose them all within braces. This looks like a variable or parameter declaration, but don't be confused. The placeholder is a type, not a variable.

Public Class RecycleBin _
        (Of T As IDisposable)
    Implements IDisposable
public class RecycleBin<T> :
        IDisposable
    where T : IDisposable