I have a problem with the VB.NET compiler that was not able to compile a class (in a separate C # assembly) that contains two method overloads with common arguments. Equivalent code in C # compiles to the same assembly without errors.
Here are two method signatures:
protected void SetValue<T>(T newValue, ref T oldValue)
protected void SetValue<T>(T? newValue, ref T? oldValue) where T : struct
Here is the code for three assemblies that demonstrate the problem. The first is C # assembly with a base class that implements common methods. The second is the C # class derived from Base, and correctly calls both SetValue overloads. The third is the VB class, also derived from Base, but does not compile with the following error message:
Error 1 It was not possible to allow overloading because the available "SetValue" is most defined for these arguments: "Protected Sub SetValue (from T As Structure) (newValue As System.Nullable (Of Integer), ByRef oldValue As System.Nullable (Of Integer)) : Not the most specific. 'Protected Sub SetValue (Of T) (newValue As System.Nullable (Of Integer), ByRef oldValue As System.Nullable (Of Integer)): No more specific.
Base class node
Example:
public class Base
{
protected void SetValue<T>(T newValue, ref T oldValue)
{
}
protected void SetValue<T>(T? newValue, ref T? oldValue) where T : struct
{
}
}
C # Derived Class
Example:
public class DerivedCSharp : Base
{
private int _intValue;
private int? _intNullableValue;
public void Test1(int value)
{
SetValue(value, ref _intValue);
}
public void Test2(int? value)
{
SetValue(value, ref _intNullableValue);
}
}
Derived class VB
Example:
Public Class DerivedVB
Inherits Base
Private _intValue As Integer
Private _intNullableValue As Nullable(Of Integer)
Public Sub Test1(ByVal value As Integer)
SetValue(value, _intValue)
End Sub
Public Sub Test2(ByVal value As Nullable(Of Integer))
SetValue(value, _intNullableValue)
End Sub
End Class
Am I doing something wrong in VB code, or are C # and VB different when it comes to general overload resolution? If I am making method arguments in Base, but not general, then everything compiles correctly, but then I have to implement SetValue for every type that I want to support.