Reputation: 12358
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
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.
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 :
What are advantages of using the first option over the second (which I might be blindly missing) ?
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
Upvotes: 1
Views: 1689
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
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