11

I've got this function:

Public Shared Function GetQueryStringValue(Of T As Structure)(ByVal queryStringVariable As String) As T
        Dim queryStringObject As Nullable(Of T) = Nothing
        If queryStringVariable <> Nothing Then
            If HttpContext.Current.Request.QueryString(queryStringVariable) IsNot Nothing Then
                queryStringObject = DirectCast(HttpContext.Current.Request.QueryString(queryStringVariable), T)
            End If
        End If

        Return queryStringObject
End Function

Which I was hoping to call like this:

Dim userId As Integer = SessionUtil.GetSessionValue(Of Integer)("uid")

I was trying to make it generic since in the end a query string value could be at least an integer or a string, but possibly also a double and others. But I get the error:

Value of 'String' cannot be converted to Type 'T'

I did this exact same thing with Session variables and it worked. Anyone know a way to make this work?

EDIT: Jonathan Allen below has a more simpler answer using CObj() or CTypeDynamic(). But the below also works from Convert string to nullable type (int, double, etc...)

Dim conv As TypeConverter = TypeDescriptor.GetConverter(GetType(T))
queryStringObject = DirectCast(conv.ConvertFrom(queryStringVariable), T)
Community
  • 1
  • 1
SventoryMang
  • 10,275
  • 15
  • 70
  • 113

2 Answers2

18

The safest way is to use CTypeDynamic. This will ensure that implicit/explicit operators are used.

Function Convert(Of T)(s As String) As T
    Return Microsoft.VisualBasic.CTypeDynamic(Of T)(s)
End Function

This will work for simple types but will fail for complex ones.

Function Convert(Of T)(s As String) As T
    Return CType(CObj(s), T)
End Function
Jonathan Allen
  • 68,373
  • 70
  • 259
  • 447
  • 1
    Great this works, I also found out this also works: `Dim conv As TypeConverter = TypeDescriptor.GetConverter(GetType(T)), then set it via queryStringObject = DirectCast(conv.ConvertFrom(queryStringVariable), T)` – SventoryMang Jul 21 '11 at 21:48
  • please check out my related but different question here: http://stackoverflow.com/questions/6792050/generic-function-with-of-t-as-what-to-accept-string-integer-datetime I ran into a problem when implementing it. – SventoryMang Jul 22 '11 at 15:10
5

I think the issue is that you can't cast a string to an Integer (or indeed, many types). It needs to be parsed instead.

I'm not sure, but CType() might do the job instead of DirectCast().

Steve Morgan
  • 12,978
  • 2
  • 40
  • 49
  • Don't think that is the issue as I can type: `DirectCast("5", Integer)` no problem. Same with `CType`. But could you provide an example of what you mean? I am somewhat familiar with parsing, but not generically... – SventoryMang Jul 21 '11 at 21:39
  • I also thought it was the same reason as this answer. Maybe VB does some extra magic. Can you put in a breakpoint and see that the value is actually convertable to an Integer? And does DirectCast("5", Integer) actually execute without error in VB? – hatchet - done with SOverflow Jul 21 '11 at 21:42
  • 2
    The code `DirectCast("5", Integer)` doesn't compile under VB 10. – Jonathan Allen Jul 21 '11 at 21:43
  • Okay I am actually wrong, My error list must have been slow to update, Jonathan Allen is right, that doesn't compile. – SventoryMang Jul 21 '11 at 21:46