views:

348

answers:

4

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?

+28  A: 

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.

Daniel LeCheminant
+1 This is quite compreshensive. I wish I can favorite an answer.
Sung Meister
+1  A: 

The where clause is used to limit the arguments that can be passed when using generics. When you create a generic class it might be in your best interest to specify an argument type depending on how you plan to use T in your class. If it anything besides what System.Object can do then it is probably best to use a constraint as you will get a compile time error vs a runtime.

example

If you create a class

class Person<T> where T : System.IComparable<T>
{
   //can now use CompareTo
}

You can not not pass this class anything that does not implement IComparable. So it is now safe to use CompareTo on anything that is passed into the the Person class.

cgreeno
+1  A: 

It's a way of restricting the type used as generic arguments. So:

where T : SomeType

Means that T must either derive from SomeType or implement the interface SomeType

Sean
+5  A: 

Additionally what the others said, you have the following too:

  • new() - T must have default constructor
  • class - T must be a reference type
  • struct - T must be a value type
leppie