¿Por qué CType se queja ( InvalidCastException ) acerca de tomar un objeto (que es realmente un Int32? ) y convertirlo en un Int64? ?
Descubrí que CTypeDynamic no tiene ningún problema (sin embargo, es tangencial, ya que estoy enfocado en Ctype ).
Aquí hay una muestra de código para reproducir el escenario.
Module Module1 Sub Main() Dim i As Int32? = 1234567891 'manual nullable -> non nullable -> non nullable -> nullable 'per https://stackoverflow.com/a/10065482/392175 Dim iNotNullable As Int32 = i.Value Dim biNotNullable As Int64 = iNotNullable Dim bi As Int64? = biNotNullable Console.WriteLine($"---Manual results---") Console.WriteLine($"i={i}") Console.WriteLine($"bi={bi}") 'CType investigation bi = Module1.xCType(Of Int64?)(i) Console.WriteLine($"---CType results---") Console.WriteLine($"i={i}") Console.WriteLine($"bi={bi}") Console.ReadLine() End Sub Public Function [xCType](Of T)(ByVal obj As Object) As T If obj Is Nothing Then Return Nothing If IsDBNull(obj) Then Return Nothing Return obj 'fails Return CType(obj, T) 'fails Return CTypeDynamic(Of T)(obj) 'succeeds End Function End ModuleTiene dos problemas, ambos relacionados con información de tipo insuficiente disponible en tiempo de compilación.
.NET no se especializa en métodos genéricos. Una compilación, basada en las restricciones, tiene que funcionar para cada valor de tiempo de ejecución del parámetro genérico.
En el momento en que el compilador ve xCType , no sabe que T es un tipo anulable, por lo que no puede elegir la regla para la conversión anulable ( S? a S a T a T? ) e incluso si se limita a un tipo anulable genérico la conversión intermedia ( S a T ) seguirá fallando porque es específica del tipo, no genérica.
obj tiene Object de tipo estático, por lo que nuevamente el compilador no sabe que el valor real pasado será anulable y no puede seleccionar la secuencia de conversión anulable. Y nuevamente, la conversión intermedia en la secuencia ( S a T ) no se puede encontrar cuando falta la información de tipo de tiempo de compilación.
CTypeDynamic supera estos dos problemas al observar el tipo de tiempo de ejecución en lugar del tipo de tiempo de compilación.