There is a legacy Visual Basic class library targetting .Net Standard 2.0 currently:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualBasic" Version="10.3.0" />
</ItemGroup>
</Project>
There is also a class inside
Public Class Class1
Public Shared Function TryGetInteger(ByVal value As Object) As Integer
Dim out As Integer
If Integer.TryParse(value, out) Then
Return out
End If
Return Integer.MinValue
End Function
Public Shared Function BooleanToInt(ByVal bValue As Object) As Integer
If (bValue = DBNull.Value) Then
Return 0
ElseIf bValue = True Then
Return 1
Else
Return 2
End If
End Function
End Class
At this point everything works fine.
But changing <TargetFramework>netstandard2.0</TargetFramework>
to 2.1 breaks the build with the following error in the Class1.TryGetInteger
function:
Requested operation is not available because the runtime library function 'Microsoft.VisualBasic.CompilerServices.Conversions.ChangeType' is not defined
How can this be fixed?
EDIT: Please disregard below idea:
The first idea comes from this closed github issue, that suggests adding <VBRuntime>Default</VBRuntime>
to the project file, but this results in error:
could not find library 'Microsoft.VisualBasic.dll'
But it is already linked as a package... Any ideas?
EDIT: As mentioned is the comments, my take on the linked github issue is a bit misleading, so I guess I'm back to the beginning with the Requested operation is not available
error.
Integer.TryParse()
expects a String, but the input argument type is Object.
You can fix the issue like this:
Public Shared Function TryGetInteger(value As Object) As Integer
Dim out As Integer
If Integer.TryParse(value.ToString(), out) Then Return out
Return Nothing 'Same as Integer.MinValue in this context
End Function
The extra ToString()
call is the same thing the old framework was doing for you implicitly. Now you're aware of it.
But really I'd do this:
Public Shared Function TryGetInteger(value As String) As Integer
Dim out As Integer
If Integer.TryParse(value, out) Then Return out
Return Nothing
End Function
Which will probably bring up a whole new set of compiler errors, but there will be value in going back and fixing them at those calling locations. Most of the errors can be fixed by adding .ToString()
to the end of value when calling the function, and any that can't were almost certainly hiding bugs.
Similarly for the BooleanToInt()
function, I'd use explicit types, and maybe overloading to get better results, like this:
Public Shared Function BooleanToInt(bValue As DBNull) As Integer
Return 0 'If this overload was selected, we know we want 0
End Function
Public Shared Function BooleanToInt(bValue As Boolean) As Integer
If bValue Then Return 1
Return 2
End Function
Public Shared Function BooleanToInt(bValue As Object) As Integer
Return 2
End Function
As a rule of thumb, anywhere you need to use the Object
type directly is a magnet for bugs. It's a smell in the code and something to avoid.