1

I've a question. I most recently changed one of my IDictionary to a IEnumerable<KeyValuePair>. This was made because this collection of items shouldn't be modified. As i can see these are the same but IEnumerable dosn't implement the Add, remove etc, this made this perfect for me and my area of using this collection.

public IDictionary<string, UserInformation> MyItems;
public IEnumerable<KeyValuePair<string, UserInformation>> MyItems;

Now to my questions.

  • Is this the smartest way to go if i don't want the collection to be modified?
  • Is there a smarter way in doing this?
  • Am i being stupid doing like this?

I found simular posts to this before but none actually explaining what to use and why.

Jonas W
  • 3,200
  • 1
  • 31
  • 44
  • 3
    IMO this is a bad solution because you lose the key-index, which is the main feature of a dictionary. Regarding read-only dictionaries, please take a look at the solution I've suggested here: http://stackoverflow.com/a/11908709/1484750 – Andre Calil Aug 20 '12 at 12:16
  • 1
    You can use `System.Collections.ObjectModel.ReadOnlyDictionary` – L.B Aug 20 '12 at 12:17
  • 1
    There really isn't enough context to answer this - how do you expect this collection to be used? How is it to be initialized? Who will be using it (you? colleagues? third parties?)? Is this part of a public API? – Oded Aug 20 '12 at 12:17

3 Answers3

5

The most important problem is that an IDictionary is designed to be used for efficient lookup. If you really only want to represent a sequence of pairs, then your approach is okay - but I wouldn't use KeyValuePair unless the relationship is really a key/value semantically... in which case I really would just use a dictionary.

You don't have to expose the dictionary, of course - you can expose methods which only fetch the value for a key (and perhaps also expose a sequence of keys, and a sequence of values).

Or you could create a read-only implementation of IDictionary<,> of course - there's a sample implementation in this answer.

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • For a second I thought that you were going to link my answer =) – Andre Calil Aug 20 '12 at 12:21
  • Thanks for the reply. I'll go with the ReadOnly implementation, seems perfect for this collection. I'll also try and change the infrastructure so i don't have to expose the dictionary, this was the beginning of why i even considered using a IEnumerable of KeyValuePair. Thank you! (in the end i can just make it private, and using get to fetch the values) – Jonas W Aug 20 '12 at 12:23
  • "in which case I really would just use a dictionary." - Why? Dictionary has more overhead than a collection of KeyValuePair, so why would you use a dictionary over a set KeyValuePair to just represent a sequence of pairs? – BornToCode Jan 30 '17 at 08:50
  • 1
    @BornToCode: Well the "key" part of "key value pair" suggests that it's going to be looked up. If it's really, really only a sequence of pairs (not key/value pairs), then sure, use a sequence - but then don't use `KeyValuePair`, basically as I said in the answer. – Jon Skeet Jan 30 '17 at 08:55
1

I would say you can wrap your IDictionary<string, UserInformation> into some class, with a single Get(...) method. Something like this:

public class DictionaryWrapper
{
   private IDictionary<string, UserInformation> _dict = .... // dictionary is PRIVATE!

   public UserInformation GetUserInfo(string key)    // method is PUBLIC
   {
      UserInformation ui;
      _dict.TryGetValue(key, out ui);
      return ui;
   }
}

In this way you:

  • limit acces to the Dictionary, and so to its public members too.
  • continue to benefit from O(1) access speed provided by the dictionary, which you lose when you use IEnumerable<..> instead.
g t
  • 7,287
  • 7
  • 50
  • 85
Tigran
  • 61,654
  • 8
  • 86
  • 123
1

By your questions,

  1. IEnumerable is a smart way of allowing of implying this is a collection that cannot be modified.
  2. There are a number of downsides of changing your return type to that,
    1. IEnumnerable<KeyValuePair<string, UserInformation>> can have duplicate keys. IDictionary can't
    2. Although the collection representation if implemented as a Dictionary means you have all of your indexes / buckets etc..., the caller does not know that. They may create their own dictionary if they need to index things.
M Afifi
  • 4,645
  • 2
  • 28
  • 48