I have a problem with the VB.NET compiler failing to compile a class (in a separate C# assembly) which contains two overloads of a method with generic arguments. The equivalent code in C# compiles against the same assembly with no errors.
Here are the 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 to three assemblies that demonstrate the problem. The first is the C# assembly with a Base class that implements the generic methods. The second is a C# class derived from Base and calls both overloads of SetValue correctly. The third is a VB class also derived from Base, but fails to compile with the following error message:
Error 1 Overload resolution failed because no accessible 'SetValue' is most specific for these arguments: 'Protected Sub SetValue(Of T As Structure)(newValue As System.Nullable(Of Integer), ByRef oldValue As System.Nullable(Of Integer))': Not most specific. 'Protected Sub SetValue(Of T)(newValue As System.Nullable(Of Integer), ByRef oldValue As System.Nullable(Of Integer))': Not most specific.
Base Class assembly
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); } }
VB Derived Class
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 the VB code, or are C# & VB different when it comes to generic overload resolution? If I make the method arguments in Base non-generic then everything compiles correctly, but then I have to implement SetValue for every type that I wish to support.