"T : class" will force the generic type specified to be a class, not a value. For example, we can make up an ObjectList class that requires the generic type specified to be a class, not a value:
class ObjectList<T> where T : class {
...
}
class SomeObject { ... }
ObjectList<int> invalidList = new ObjectList<int>(); //compiler error
ObjectList<SomeObject> someObjectList = new ObjectList<SomeObject>(); //this works
This forces an invariant on your generic type T that otherwise might not be enforceable. "T : struct" would work the same way. Note that you can also use this construct to enforce not only that the type T is a class, but also that it matches an interface. The code sample I took this from also has
class MyList<T> where T : class, IEntity { ... }
which forces T to be a class AND also be an IEntity.