c#,generics,constraints – What Does ‘where T : somevalue’ Mean in C#

c++constraintsgenerics

What does where T : somevalue mean? I just saw some code that said where T : Attribute. I think this has something to do with generics but I am not sure what this means or what it is doing.

Does anyone know?

Best Answer

It is a constraint on a type parameter, meaning that the type T given to a generic class or method must inherit from the class Attribute

For example:

public class Foo<T> : 
   where T : Attribute
{
    public string GetTypeId(T attr) { return attr.TypeId.ToString(); }
 // ..
}

Foo<DescriptionAttribute> bar; // OK, DescriptionAttribute inherits Attribute
Foo<int> baz; // Compiler error, int does not inherit Attribute

This is useful, because it allows the generic class to do things with objects of type T with the knowledge that anything that is a T must also be an Attribute.

In the example above, it's okay for GetTypeId to query the TypeId of attr because TypeId is a property of an Attribute, and because attr is a T it must be a type that inherits from Attribute.

Constraints can also be used on generic methods, with the same effect:

public static void GetTypeId<T>(T attr) where T : Attribute
{
   return attr.TypeId.ToString();
}

There are other constraints you can place on a type; from MSDN:

where T: struct

The type argument must be a value type. Any value type except Nullable can be specified.

where T : class

The type argument must be a reference type; this applies also to any class, interface, delegate, or array type.

where T : new()

The type argument must have a public parameterless constructor. When used together with other constraints, the new() constraint must be specified last.

where T : <base class name>

The type argument must be or derive from the specified base class.

where T : <interface name>

The type argument must be or implement the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic.

where T : U

The type argument supplied for T must be or derive from the argument supplied for U. This is called a naked type constraint.