where
can serve two purposes in C#: type constraining in a generic argument, and filtering LINQ queries.
In a generic class, let’s consider
public class Cup<T>
{
// ...
}
T is called a type parameter. The class definition can impose constraints on the actual types that can be supplied for T.
The following kinds of constraints can be applied:
value type
In this case only struct
s (this includes ‘primitive’ data types such as int
, boolean
etc) can be supplied
public class Cup<T> where T : struct
{
// ...
}
reference type
In this case only class types can be supplied
public class Cup<T> where T : class
{
// ...
}
hybrid value/reference type
Occasionally it is desired to restrict type arguments to those available in a database, and these will usually map to value types and strings. As all type restrictions must be met, it is not possible to specify where T : struct or string
(this is not valid syntax). A workaround is to restrict type arguments to [IConvertible](<https://msdn.microsoft.com/en-us/library/system.iconvertible(v=vs.110).aspx>)
which has built in types of “… Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, and String.” It is possible other objects will implement IConvertible, though this is rare in practice.
public class Cup<T> where T : IConvertible
{
// ...
}
default constructor
Only types that contain a default constructor will be allowed. This includes value types and classes that contain a default (parameterless) constructor