Equals not being called by IList.Contains

  • Thread starter Thread starter matt tagliaferri
  • Start date Start date
M

matt tagliaferri

I'm implementing a typed collection class that can't include
duplicates.

The Add method of the collection class is as follows:

Public Function Add(ByVal o As TeamListEntry) As Integer

If List.Contains(o) Then
Return -1
Else
Return List.Add(o)
End If

End Function

According to the Docs, the Contains method should call my overloaded
Equals method (below) to determine Equality, but it never gets called.

Public Overloads Function Equals(ByVal aTeam As TeamListEntry) As
Boolean
Return FTeam.Equals(aTeam.Team)
End Function

Any ideas?
matt tag
 
Hi Matt,

What does your class inherit from ?

The Equals override will be that of the base class. It looks to me as if
your List is a member of your class - not its base. That means that you
haven't overriden List.Equals, so List.Contains would have no knowledge of
<your> Equals.

But this is only guessing from what you've shown. If I'm wrong, could you
show us more of your class?

Regards,
Fergus
 
matt tagliaferri said:
I'm implementing a typed collection class that can't include
duplicates.

The Add method of the collection class is as follows:

Public Function Add(ByVal o As TeamListEntry) As Integer

If List.Contains(o) Then
Return -1
Else
Return List.Add(o)
End If

End Function

According to the Docs, the Contains method should call my
overloaded Equals method (below) to determine Equality, but it never
gets called.

Public Overloads Function Equals(ByVal aTeam As TeamListEntry)
As
Boolean
Return FTeam.Equals(aTeam.Team)
End Function

Any ideas?
matt tag


Public Overloads Overrides Function Equals(ByVal aTeam As Object) As Boolean

You can not use "As TeamListEntry" for the argument, because the function
called from the List, is the one with the signature "As Object". In other
words, the List object can not call your Equals method because it does not
know the type "TeamListEntry".

After changing the signature, you must type-cast the reference:

Return FTeam.Equals(DirectCast (aTeam, TeamListEntry).Team)
 
But this is only guessing from what you've shown. If I'm >>wrong,
could you show us more of your class?

Sure. Here is the base class (inherits from Object), the list (inherits
from CollectionBase), and some code to fill the list and bind it to a
listbox. The intent is to remove the duplicate entries.

Public Class TeamListEntry

Private FTeam As String

Public Sub New(ByVal cTeam As String)
MyBase.new()
Team = cTeam
End Sub

Property Team() As String
Get
Return FTeam
End Get
Set(ByVal Value As String)
FTeam = Value
End Set
End Property

Public Overloads Function Equals(ByVal aTeam As TeamListEntry) As
Boolean
Return FTeam.Equals(aTeam.Team)
End Function

End Class

-------------------------------------------
Public Class TeamList
Inherits CollectionBase

Default Public Property Item(ByVal index As Integer) As
TeamListEntry
Get
Return List.Item(index)
End Get
Set(ByVal Value As TeamListEntry)
List.Item(index) = Value
End Set
End Property

Public Function Add(ByVal o As TeamListEntry) As Integer

If List.Contains(o) Then
Return -1
Else
Return List.Add(o)
End If

End Function

End Class

-----------------------------
Public Class Form1
Inherits System.Windows.Forms.Form

Private FTeams As TeamList

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

FTeams = New TeamList
FTeams.Add(New TeamListEntry("CLE"))
FTeams.Add(New TeamListEntry("CLE"))
FTeams.Add(New TeamListEntry("BUFFALO"))
FTeams.Add(New TeamListEntry("AKRON"))
FTeams.Add(New TeamListEntry("LAKE COUNTY"))
FTeams.Add(New TeamListEntry("KINSTON"))

ListBox1.DataSource = FTeams
ListBox1.DisplayMember = "Team"

End Sub
End Class
 
Hi Matt,

I don't know if you've gone away happy or haven't realised, but Armin has
given you the solution.

You had :
Public Overloads Function Equals(ByVal aTeam As TeamListEntry) _
As Boolean

which can't override the base class Equals because it has a different
parameter type. Thus the compiler has you use Overloads but disallows
Overrides. The List will not therefore be able to call it.

If you use Armin's version:

Public Overloads Overrides Function Equals(ByVal aTeam As Object) _
As Boolean
Return FTeam.Equals(DirectCast (aTeam, TeamListEntry).Team)
End Function

then this time you <must> use Iverrides and everything will work fine.

Regards,
Fergus
 
Back
Top