You can constrain the generic type by IConvertible
and Structure
. The following data types implements the IConvertible interface:
- System.Boolean
- System.Byte
- System.Char
- System.DateTime
- System.DBNull
- System.Decimal
- System.Double
- System.Enum
- System.Int16
- System.Int32
- System.Int64
- System.SByte
- System.Single
- System.String
- System.UInt16
- System.UInt32
- System.UInt64
Here's a rewrite of the code found in the link provided by SLaks:
Public Function Square(Of T As {IConvertible, Structure})(x As T) As T
'TODO: If (GetType(T) Is GetType(Date)) Then Throw New InvalidOperationException()
Dim left As ParameterExpression = Expression.Parameter(GetType(T), "x")
Dim right As ParameterExpression = Expression.Parameter(GetType(T), "x")
Dim body As BinaryExpression = Expression.Multiply(left, right)
Dim method As Func(Of T, T, T) = Expression.Lambda(Of Func(Of T, T, T))(body, left, right).Compile()
Return method(x, x)
End Function
Reference: https://jonskeet.uk/csharp/miscutil/usage/genericoperators.html