Search code examples
vb.netinterfaceobsolete

How do I implement an interface with an obsolete method in VB.NET without suppressing warnings?


I have an interface I, and I have just decided to deprecate method OldMethod (because it's badly named, because I want additional parameters, you name it) and advise users of my library to use NewMethod instead. Thus, I have extended I as follows:

Interface I
    <Obsolete("Use NewMethod instead.")>
    Sub OldMethod()
    Sub NewMethod()
End Interface

However, now all my classes implementing I get a compiler warning:

Class C
    Implements I

    ' The following line yields warning BC40000 
    Public Sub OldMethod() Implements I.OldMethod
        Throw New NotImplementedException()
    End Sub

    Public Sub NewMethod() Implements I.NewMethod
        Throw New NotImplementedException()
    End Sub
End Class

This doesn't make sense to me: To implement I (which, as a whole, is not obsolete), I need to implement OldMethod. The corresponding code in C# compiles perfectly fine and does not produce warnings:

interface I
{
    [Obsolete("Use NewMethod instead.")]
    void OldMethod();
    void NewMethod();
}

class Explicit : I
{
    public void NewMethod() { throw new NotImplementedException(); }
    public void OldMethod() { throw new NotImplementedException(); }
}

class Implicit : I
{
    void I.NewMethod() { throw new NotImplementedException(); }
    void I.OldMethod() { throw new NotImplementedException(); }
}

I know that I could just suppress the warning in VB, but, usually, a compiler warning indicates that you are doing something that should not be done in that way.

How can I implement an interface with an obsolete member in VB.NET without getting an obsolete warning?


Solution

  • Fleshing out this answer from my comment.

    The implementing class must implement the Obsolete member to fulfill the contract, but when the interface method is marked as Obsolete you must also mark the corresponding method as Obsolete to satisfy the compiler that the implementation of the Obsolete member is not to be used.

    Public Interface I
        <Obsolete("Use NewMethod instead.")>
        Sub OldMethod() 
        Sub NewMethod()
    End Interface
    
    Public Class C
        Implements I
    
        <Obsolete("Use NewMethod instead.")>
        Public Sub OldMethod() Implements I.OldMethod ' No warning
            Throw New NotImplementedException()
        End Sub
    
        Public Sub NewMethod() Implements I.NewMethod
            Throw New NotImplementedException()
        End Sub
    End Class
    

    Although not entirely relevant for this particular question, whilst researching I found this blog post by Grant Winney explaining why it is a good idea to mark obsolete members on the interface member itself (as well as on the implementing member)