2

I have read

When should I choose inheritance over an interface when designing C# class libraries?

I believe I understand is-a vs must-do relationship. Having said all that here is my dilemma.

I want to implement a Collection of key value pairs most likely object. I need to add to the add and remove events only to do validation, check for duplication and some tracking stuff.

If I implement IDictionary it seems that it is a bit of an over kill to implement all the Idictionary<>, ICollection<>, IEnumerable<>, and IEnumerable. Yes most of them are one liners.

It is not recommended to inherit from Dictionary as it was never meant to be extended, shadowing the Add and remove.

Finally I can just implement a private variable and then expose the methods I want or need for the project

Any suggestions on the direction to go?

Community
  • 1
  • 1
Mike
  • 5,918
  • 9
  • 57
  • 94

4 Answers4

2

You should use composition and encapsulate a dictionary inside your class (the private variable option). This way, you only expose to the outside world the operations that make sense for your object and the fact that you use a dictionary is a mere implementation detail.

You should only implement IDictionary<,> or inherit from Dictionary<,> if your class is a generic dictionary with some special characterists.

Jordão
  • 55,340
  • 13
  • 112
  • 144
0

The simplest approach would be to implement the IDictionary as an instance variable and wrap the Add and Remove methods in Add and Remove methods in your class that perform validation before adding or removing the object to or from the dictionary.

Isaac Overacker
  • 1,385
  • 10
  • 22
0

Inheritance is for when you need to inherit implementation. Otherwise, if you want to inherit interface, bit not implementation, uses interfaces.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

I would suggest perhaps designing some of your own dictionary-ish interfaces which include the functionality you're interested in. Among other things, I would suggest having some interfaces which exist purely for reading the interface, and some which allow read-write access. Among other things, if you have a read-only interface, methods which don't care whether a particular dictionary is mutable or immutable will be able to use an IReadableDict (implemented by both mutable and immutable dictionaries) while routines that require either that a dictionary be mutable or that it be immutable will be able to specify that. Further, segregating out some other interfaces will allow maximum possibilities for covariance and contravariance. For example, code which is expecting an IReadableDict<String, Animal> could be perfectly happy with a Dict<String, Cat> even though code which was expecting an IReadWriteDict<String, Animal> would not be able to accept an Dict<String, Cat>. Likewise, code which only needs to know the count of a dictionary could accept a non-generic ICountable which exposes a Count method, and code which only needs to know whether a certain key exists could accept a non-generic IQueryExistence (note that one can perfectly legitimately check whether a Dict<Cat, PurrVolume> contains a particular instance of Dog; the answer will be 'no', but the question is valid).

supercat
  • 77,689
  • 9
  • 166
  • 211