frictionlesspulley
frictionlesspulley

Reputation: 12358

Using Objects as Keys in Dictionary

Is it a good practice to use your domain objects as keys in a Dictionary ?

I have a scenario where I populate my domain object using NHibernate.

For performing business logic I need to look-up Dictionary. I can make use of Either

IDictionary<int, ValueFortheObject> 

or

Dictionary<DomainObject, ValueFortheObject>

The second options seems better to me as

  1. I can write easier test cases and can use real domain objects in test cases as well rather than using Mock<DomainObject> (if I go with the first option) since setter on the Id is private on ALL domain objects.

  2. The code is more readable as Dictionary<Hobbit,List<Adventures>> is more readable to me than Dictionary<int,List<Adventures>> with comments suggesting int is the hobbitId especially when passing as parameters

My questions are :

  1. What are advantages of using the first option over the second (which I might be blindly missing) ?

  2. Will be any performance issues using the second approach?

Update 01:

My domain models implement those and they DO NOT get mutated while performing the operations.

Will there be issues with performance using them as keys ? or am I completely missing the point here and performance / memory are not related to what keys are being used?

Update 02:

My question is

  1. Will there be any issues with performance or memory if I use Objects as keys instead of primitive types and WHY / HOW ?

Upvotes: 1

Views: 1689

Answers (2)

tvanfosson
tvanfosson

Reputation: 532435

@ScottChamberlain gives you the overall issue, but your use cases could argue either way. Some questions you should ask yourself are: what does it mean for two business objects to be equal? Is this the same or different if they are being used as a key in a dictionary or if I'm comparing them elsewhere? If I change an object, should it's value as a key change or remain the same? If you use overrides for GetHashCode() and Equals(), what is the cost of computing those functions?

Generally I am in favor of using simple types for keys as there is a lot of room for misunderstanding with respect to object equality. You could always create a custom dictionary (wrapper around Dictionary<Key,Value>) with appropriate method if readability is your highest concern. You could then write the methods in terms of the objects, then use whatever (appropriate) property you want as the key internally.

Upvotes: 1

Scott Chamberlain
Scott Chamberlain

Reputation: 127543

The biggest issue you will run in to is you must not mutate your key object while it is performing it's roll as a key.

When i say "mutate" I mean your key object must implement Equals and GetHashCode to be used as a key for a dictionary. Anything you do to the object while it is being used as a key must not change the value of GetHashCode nor cause Equals to evaluate to true with any other key in the collection.

Upvotes: 4

Related Questions