views:

47

answers:

3

I'm working on a .NET phone application where I have a list of items in memory that are displayed to the user. When the user clicks on an item in the user interface, they'll be brought to the "details" view for that item in a second view. I'm currently using an identity property in my class to reference unique items in the list, but I'm wondering if there is a better way.

I'm using System.Windows.Navigationto set up UriMappings like so:

<nav:UriMapping Uri="/Items/{itemId}" 
                MappedUri="/Views/Items.xaml?itemId={itemID}" />

I then use the NavigationService to navigate like so:

NavigationService.Navigate(new Uri("/Items/" + item.id.ToString(),
                                   UriKind.Relative));

All of this works great, but I don't know that I like needing to include an identity column for my Item class just so that can have a unique string identifer to pass in to the MappedUri query string. My user interface control that shows the list gives me the underlying Item object in the SelectionChanged event, so I'm wondering if there's a way to "match" that Item object with a unique string value to its corresponding reference in the list. If I could provide a simple object reference to the navigation service, this would be easy, but I'm not sure how to do it with a string value. Is this what GetHashCode() is for, and if so, how do I use it correctly?

+5  A: 

No, GetHashCode is not intended to uniquely identify objects.

The default implementation of the GetHashCode method does not guarantee unique return values for different objects. Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework. Consequently, the default implementation of this method must not be used as a unique object identifier for hashing purposes.

It is designed for storing objects in buckets (for example in a dictionary) so that they can be quickly retrieved. The hash codes for two equal objects must be equal, but the hash codes for two different objects do not have to be different.

I think adding an Id field is a fine solution. If you don't like adding a new field just to give an object an identity you can try to find some combination of the existing fields that is guarateed to uniquely identify your object and concetenate their string representations with a suitable separator. Be careful that the separator cannot occur in any of the fields.

Mark Byers
+2  A: 

There's a GUID which you can use that maps to each string in the list, by calling a NewGuid method of the Guid class, one can generate a Guid and use that as a string type via ToStringmethod and use it for hashing strings.

tommieb75
I don't see how that helps. Given just the GUID, how would he retrieve the right item? He'd have to remember the mapping from GUID to Item... at which point he's back to the original situation of having an ID.
Jon Skeet
+2  A: 

You definitely want to provide the item's ID. Bear in mind that your application may be tombstoned, so the object may not even be in memory any more when you try to navigate to that page. You need to be able to restore the application to the page with no information other than the URL and whatever's been serialized to temporary or permanent storage (typically in OnNavigateFrom).

Using GetHashCode() for this not only doesn't guarantee uniqueness, but it's highly unlikely to work in terms of the newly restored application, too. Life gets a lot harder when you're trying to display the details of something where you haven't really got an ID... but it doesn't sound like you're really in that position.

As it looks like you've got an ID, use it as an ID. Why would you want to use anything else? If you don't have an ID but can easily add one, do so. You want a way of uniquely identifying an object... that's exactly what an ID is for.

Jon Skeet
You bring up a good point that since I've already got an ID, I might as well use it. Since I've just begun modeling all of the classes for my application, I thought I might see if there was an alternative to using an ID before I got too far into that project. Thanks for the suggestions.
Ben McCormack