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.
I suspect that what you want based on your comments on Jon's answer is a way to constrain a type parameter to either blittable types or unmanaged types.
An "unmanaged type" is a type whose definition precludes any reference to memory tracked by the garbage collector; you can only make pointer types out of unmanaged types. Blittable types are those types which can be marshalled from managed to unmanaged code without any modification to their bits; they are a subset of the unmanaged types.
A number of people have told us that it would be quite handy to have a generic constraint that constrains a type parameter to be only an unmanaged type. We have experimented with prototypes of C# and the CLR that have this constraint, but have no plans at this time to actually put the feature into the product. If you can describe the scenario that is motivating the feature request, that would help us prioritize the feature against the hundreds of other features that are also possible.
Best Answer
It enforces that T has to be a nullable reference type.
The type you set in for T, must derive from
object?
.It's a new feature in C#8, to explictly declare a type as nullable. if you have
You document, it's OK to Add null;