I have a class with an overloaded assignment operator
Public Class Timestamp
ReadOnly _value As String
Public Sub New(value As String)
Me._value = value
Public Shared Widening Operator CType(ByVal input As String) As Timestamp
Return New Timestamp(input)
This allows both of the following widening conversions to occur:
Dim t1 As Timestamp = "1314"
Dim t2 As Timestamp = CType("1314", Timestamp)
So it will happily change from type
String into type
However, if I have a method that takes Timestamp as a generic, the conversion no longer works.
For example, for the following method:
Private Function GenericCast(Of T)(input As Object, output As T) As T
Return CType(input, T)
If I call it like this:
Dim t3 as Timestamp
t3 = GenericCast("1314", t3)
I'll get the following error:
Unable to cast object of type 'System.String' to type 'Timestamp'.
But we already know that I definitely can convert between those types.
Why does it it not work with Generics at runtime?
A potential solution is to use
CTypeDynamic instead of
Private Function GenericCastV2(Of T)(input As Object, output As T) As T output = CTypeDynamic(Of T)(input) Return output End Function
I know this does not answer your "why" question, but it would just be supposition on my part. My gut answer is that it has to do with the decisions that the VB compiler makes in deciding which helper method to call to complete conversion. As a potential clue to the problem, following concept function will not event compile as valid conversion from String for all types would be required.
Private Function GenericCastConcept(Of T)(input As Object, output As T) As T output = CType(input.ToString, T) Return output End Function