Logic Error

Nate Bross

Contributor
Joined
Apr 6, 2005
Messages
601
Location
Chicago, IL
I've got a collection of 'SearchResults' that I convert into an ArrayList of custom classes, because the collection has a large amount of data I do not care about.

Custom Class Deffinition
Visual Basic:
Public Class Item
    Dim sTitle As String
    Dim dPrice As Double
    Dim dBuyIt As Double
    Dim sItemID As String
    Dim sURL As String
    Dim dStartDate As Date

    Public Sub New(ByVal sT As String, ByVal dP As Double, ByVal dB As Double, ByVal sID As String, ByVal URL As String, ByVal dSD As Date)
        sTitle = sT
        dPrice = dP
        dBuyIt = dB
        sItemID = sID
        sURL = URL
        dStartDate = dSD
    End Sub

    Public Property Title() As String
        Get
            Return sTitle
        End Get
        Set(ByVal value As String)
            sTitle = value
        End Set
    End Property

    Public Property Price() As Double
        Get
            Return dPrice
        End Get
        Set(ByVal value As Double)
            dPrice = value
        End Set
    End Property

    Public Property BuyItNowPrice() As Double
        Get
            Return dBuyIt
        End Get
        Set(ByVal value As Double)
            dBuyIt = value
        End Set
    End Property

    Public Property ItemID() As String
        Get
            Return sItemID
        End Get
        Set(ByVal value As String)
            sItemID = value
        End Set
    End Property

    Public Property URL() As String
        Get
            Return sURL
        End Get
        Set(ByVal value As String)
            sURL = value
        End Set
    End Property

    Public Property StartDate() As Date
        Get
            Return dStartDate
        End Get
        Set(ByVal value As Date)
            dStartDate = value
        End Set
    End Property
End Class

I get a new collection every few seconds (usually containing no new data), but every now and then there are new items in the collection. When this happens I want to notify the user and tell them what is new since last time.

Here's how I am figuring out if a new item has appeared.
Visual Basic:
        For Each result As SearchResultItemType In results
                tbString.AppendLine(result.Item.ItemID & vbTab & result.Item.SellingStatus.CurrentPrice.Value() & vbTab & result.Item.ListingDetails.StartTime)

                Dim tItem As New Item(result.Item.Title.ToString(), result.Item.SellingStatus.CurrentPrice.Value(), 0, result.Item.ItemID(), result.Item.ListingDetails.ViewItemURL.ToString(), result.Item.ListingDetails.StartTime())
                'BuyItNowPrice returns nothing not 0 if no value is specified
                If result.Item.BuyItNowPrice IsNot Nothing Then
                    tItem.BuyItNowPrice = result.Item.BuyItNowPrice.Value()
                End If

                If OldItems.IndexOf(tItem) > 0 Then
                    'The Item is In the Array
                    Dim x As Long = 0
                Else
                    UnViewed.Add(tItem)
                    OldItems.Add(tItem)
                End If
            Next

What happens is that every item shows up in my UnViewed ArrayList.

I know there's alot of stuff here, but if you need more information let me know and I'll provide what I can.
 
IIRC .IndexOf calls the .Equals method of the class to compare them and decide if they are the ame or not - for reference types this simply checks if the object is in the same memory location and doesn't compare the values themselves.
To make this work you will need to override the Equals method in your Item class to perform a compare of two Item objects.
 
I'll explain what I think is happening, perhaps somebody else will have a better idea, but here goes. Obiviously the item is always being added to the UnViewed collection because IndexOf is always returning a zero. Now I believe the IndexOf method uses Object.Equals to compare your search object to the collection and I think this compares references not values. Whilst the item you are searching for contains the same values it is not actually the same object.

Heres a simplified example...
Visual Basic:
Public Class TestClass
    Dim strName As String

    Public Sub New(ByVal num As Single)
        strName = "Name" & num.ToString()
    End Sub

    Public Property Name() As String
        Get
            Return strName
        End Get
        Set(ByVal value As String)
            strName = value
        End Set
    End Property
End Class

Public Sub Test()
        Dim oldItems As New ArrayList

        For i As Single = 0 To i < 10
            Dim tmpClass As TestClass = New TestClass(i)
            oldItems.Add(tmpClass)
        Next

        ' create an item with same name and compare that
        Dim searchClass As TestClass = New TestClass(2)

        If (oldItems.IndexOf(searchClass) > 0) Then
            MessageBox.Show("Item Found")
        Else
            MessageBox.Show("Item Not Found")
        End If

        ' prove that its not a boxing error
        For i As Single = 0 To i < 10
            Dim tmpClass As TestClass = CType(oldItems(i), TestClass)
            If Object.Equals(tmpClass, searchClass) Then
                Console.WriteLine("Item Found")
            Else
                Console.WriteLine("Item not found")
            End If
        Next

        ' create reference and search for that
        searchClass = CType(oldItems(2), TestClass)

        If (oldItems.IndexOf(searchClass) > 0) Then
            MessageBox.Show("Item Found @ " + oldItems.IndexOf(searchClass))
        Else
            MessageBox.Show("Item Not Found")
        End If
End Sub
I hope I converted that correctly, I actually tested it in c#.

EDIT:- beaten to the punch....
 
Worked like a charm....

Added this method to the Item class
Visual Basic:
Public Override Equals(obj as Object)
    If obj.ItemID = me.ItemID Then
        Return True
    Else
        Return False
    End If
End Sub

Not a catch all solution, but it will work for my purposes.
 
Back
Top