vb.netoverridingshadowequals-operator

Weird error message when implementing IEquatable


Class gridTradingState
    Implements IEquatable(Of gridTradingState)


    Public Overrides Function Equals(other As gridTradingState) As Boolean Implements IEquatable(Of gridTradingState).Equals
        '    Throw New NotImplementedException()

        Return True
    End Function
    ...


End Class

That's a very simple function right?

Well, I got this error

Severity Code Description Project File Line Suppression State Error BC30284 function 'Equals' cannot be declared 'Overrides' because it does not override a function in a base class. nicehash2 C:\Users\whatever\Dropbox\vb.net\gridtrading.vb 10 Active

Okay. So I cannot declare Equals as overrides because it does not override a function in a base class.

What is the base class? Who knows. But given that gridTradingState doesn't inherit anything I presume it must be Object class

So I remove the keyword overrides

and I got

Severity    Code    Description Project File    Line    Suppression State
Warning BC40005 function 'Equals' shadows an overridable method in the base class 'Object'. To override the base method, this method must be declared 'Overrides'.  nicehash2   C:\Users\teguh\Dropbox\vb.net\gridtrading.vb    10  Active

I can add the keyword shadow to get the error away. But it feels weird.

If my base class have and overideable function called Equals why I get the first warning and if my base class does not have Equals why do I get the second warning.

Either must be true right?

Now a good answer will be very detailed and also mention related issues.

What base class are they talking about? Object?

What function do they think I am overriding or shadowing?

What is the proper way to implement Equals anyway.

I've heard I should also implement getHash or something. However, IEquatable truly doesn't have anything else. Why?

I am not trying to ask several questions at once. More like I want detailed answer of why I got this silly errors/warnings

namespace System
{
    //
    // Summary:
    //     Defines a generalized method that a value type or class implements to create
    //     a type-specific method for determining equality of instances.
    //
    // Type parameters:
    //   T:
    //     The type of objects to compare.
    [__DynamicallyInvokable]
    public interface IEquatable<T>
    {
        //
        // Summary:
        //     Indicates whether the current object is equal to another object of the same type.
        //
        // Parameters:
        //   other:
        //     An object to compare with this object.
        //
        // Returns:
        //     true if the current object is equal to the other parameter; otherwise, false.
        [__DynamicallyInvokable]
        bool Equals(T other);
    }
}

To further investigate this issue, I add a line

Dim b = MyBase.Equals(other)

Right clicking MyBase confirms my suspicion that MyBase is simply Object.

So I look at the code and this is what I see

    //
    // Summary:
    //     Determines whether the specified object is equal to the current object.
    //
    // Parameters:
    //   obj:
    //     The object to compare with the current object.
    //
    // Returns:
    //     true if the specified object is equal to the current object; otherwise, false.
    [__DynamicallyInvokable]
    public virtual bool Equals(object obj)
    {
        return RuntimeHelpers.Equals(this, obj);
    }

I use https://icsharpcode.github.io/CodeConverter/

And I get the vb.net version.

and the vb.net version of that code is a bit like

Public Overridable Function Equals(ByVal obj As Object) As Boolean
    Return RuntimeHelpers.Equals(Me, obj)
End Function

'
' Summary:
'     Determines whether the specified object instances are considered equal.
'
' Parameters:
'   objA:
'     The first object to compare.
'
'   objB:
'     The second object to compare.
'
' Returns:
'     true if the objects are considered equal; otherwise, false. If both objA and
'     objB are null, the method returns true.
<__DynamicallyInvokable>
Public Shared Function Equals(ByVal objA As Object, ByVal objB As Object) As Boolean
    If objA Is objB Then
        Return True
    End If

    If objA Is Nothing OrElse objB Is Nothing Then
        Return False
    End If

    Return objA.Equals(objB)
End Function

So Class Object does have an overridable function called Equals

So why do I get the second warning?

My guess is because my Equals function took another gridTradingState object and not another Object object. But that's what I want right?

So where do I went wrong?


Solution

  • Just get rid of the Overrides keyword and you're done. Your type inherits Object because you're not specifying any other base type explicitly. Object has no Equals method with that signature so there's nothing to override or shadow. You're overloading the Equals method, i.e. there are multiple implementations with different signatures, but you don't need to specify that explicitly when the overloads are in different types.

    EDIT:

    I tell a lie. You are overloading and you do need the Overloads keyword in order to avoid the warning you describe:

    Public Overloads Function Equals(other As gridTradingState) As Boolean Implements IEquatable(Of gridTradingState).Equals