问题描述:

Setup

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

End Sub

Public Shared Widening Operator CType(ByVal input As String) As Timestamp

Return New Timestamp(input)

End Operator

End Class

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 Timestamp.

Problem

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)

End Function

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 CType.

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
相关阅读:
Top