5

I have a VB.NET function as below, the parameter 'x' that is passed to the function is of Type 'Single'. However, I want to write the function so that it can accept any numeric type such as 'Single', 'Double' and 'Integer'. I know one way of doing that is to write 3 functions with the same names, but it would be so tedious. Can anyone suggest any idea? Thank you.

Public Function Square(x As Single) As Single
  Return x * x
End Function
N.T.C
  • 658
  • 2
  • 9
  • 20
  • http://www.yoda.arachsys.com/csharp/genericoperators.html – SLaks Aug 12 '14 at 01:55
  • Complementary link http://converter.telerik.com/ - It doesn't seem to play too well with lambdas (Or VB just sucks that much? I don't know) – Machinarius Aug 12 '14 at 02:01
  • Although its pretty easy to do generic functions. You can't use operators in the method body. – Aron Aug 12 '14 at 02:05
  • 3
    That method is not really a good candidate for being generic because there's no constraint that you can apply to a generic type parameter that will include all the types you want and exclude all others. There's no common base type or interface that just numeric types inherit or implement. You should stick with overloading. Don't use features like generics just because you can. – jmcilhinney Aug 12 '14 at 03:06

3 Answers3

11

try following method

Public Function Square(Of T)(ByVal x As Object) As T
    Dim b As Object = Val(x) * Val(x)
    Return CType(b, T)
End Function

You can use above function like this

Dim p As Integer = Square(Of Integer)(10)
Dim d As Double = Square(Of Double)(1.5)
Shell
  • 6,818
  • 11
  • 39
  • 70
  • 1
    I am just curious about How expensive it would be if that function is called quite a lot. Apparently CType would take some computational resources? – N.T.C Aug 12 '14 at 04:45
2

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

tukaef
  • 9,074
  • 4
  • 29
  • 45
Bjørn-Roger Kringsjå
  • 9,849
  • 6
  • 36
  • 64
2

The code allows any value to posted via Arg but only numeric values will be processed. The returned value must be double because Val returns double only.

The Of T allows for generic object types to be presented.

   Private Function sqr(Of T)(Arg As T) As Double
    If IsNumeric(Arg) Then
        Return Val(Arg) * Val(Arg)
    Else
        Return 0
    End If

  End Function
Tripweed
  • 21
  • 2