0

I want to retrieve the phone number for Bill from phoneBook.

class PersonsName
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

// Dictionary Class, add contacts to phone book
Dictionary<PersonsName, int> phoneBook = new Dictionary<PersonsName, int>()
{
    {new PersonsName {FirstName = "Bill", LastName = "Gates" }, 5550100 },
    {new PersonsName {FirstName = "Mark", LastName = "Zuckerberg" }, 5551438 }
};

Why does the following give me an exception where the key is not found? How can I retrieve the phone number without looping through the dictionary?

PersonsName personA = new PersonsName { FirstName = "Bill", LastName = "Gates" };
int billssNumber = phoneBook[personA]; //key not found
DRockClimber
  • 137
  • 2
  • 9
  • If you really need it, you will have to overwrite the Equals method. Here is an example: http://stackoverflow.com/questions/634826/using-an-object-as-a-generic-dictionary-key – Jannik Feb 06 '17 at 05:52
  • 1
    You must override `GetHashCode` and `Equals` **and** make your object read-only to use it as a key in a dictionary. – Enigmativity Feb 06 '17 at 05:54
  • @Jannik - Please don't delete things like that. It makes it hard to understand the comment history. – Enigmativity Feb 06 '17 at 05:56
  • 1
    The way you are getting the elements is wrong, Try like this. `PersonsName personA = new PersonsName { FirstName = "Bill", LastName = "Gates" }; int billssNumber = phoneBook.First(x=>x.Key.FirstName==personA.FirstName &&x.Key.LastName==personA.LastName).Value;` – M. Adeel Khalid Feb 06 '17 at 05:57
  • 1
    @MAdeelKhalid: this will perform O(N) search inside `Keys` collection instead of searching by hash code. So, there won't be any benefit from using dictionary - the same performance could be achieved using regular collection, such as `List<>`. – Dennis Feb 06 '17 at 06:02
  • @Dennis He does make the point though that if the key type doesn't correctly overwrite `Equals` and `GetHashCode`, a linear lookup is the only way to retrieve a given value from a `Dictionary`. That being said, the aforementioned overriding approach is the much better option when at all possible. – Abion47 Feb 06 '17 at 06:07

1 Answers1

2

You should override your GetHashCode() and Equals() of your PersonsName class. This link should help you: Use custom object as Dictionary Key

Hope it helps!

Community
  • 1
  • 1
mindOfAi
  • 4,412
  • 2
  • 16
  • 27
  • so how would I get a specific value after overriding those methods? – DRockClimber Feb 07 '17 at 03:16
  • If you implement it propertly, you can access it by still doing this: `int billssNumber = phoneBook[personA];` – mindOfAi Feb 07 '17 at 03:21
  • Cool it worked. Are the Equals() and GetHashCode() methods implemented in the background? I never called them so I assume generics use them that way? – DRockClimber Feb 09 '17 at 05:01
  • For the GetHashCode() method I made it return this: return FirstName.GetHashCode() ^ LastName.GetHashCode(); but I don't really know what the ^ symbol stands for. Would you happen to know? – DRockClimber Feb 09 '17 at 05:03