Nate Bross Posted February 1, 2006 Posted February 1, 2006 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 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. 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. Quote ~Nate� ___________________________________________ Please use the [vb]/[cs] tags on posted code. Please post solutions you find somewhere else. Follow me on Twitter here.
Administrators PlausiblyDamp Posted February 1, 2006 Administrators Posted February 1, 2006 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Cags Posted February 1, 2006 Posted February 1, 2006 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... 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.... Quote Anybody looking for a graduate programmer (Midlands, England)?
Nate Bross Posted February 1, 2006 Author Posted February 1, 2006 Thanks alot for the help, that's what I did not know. I'll let you know how the new Equals method I use works. Quote ~Nate� ___________________________________________ Please use the [vb]/[cs] tags on posted code. Please post solutions you find somewhere else. Follow me on Twitter here.
Nate Bross Posted February 3, 2006 Author Posted February 3, 2006 Worked like a charm.... Added this method to the Item class 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. Quote ~Nate� ___________________________________________ Please use the [vb]/[cs] tags on posted code. Please post solutions you find somewhere else. Follow me on Twitter here.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.