2

I need to define a class with an internal collection object to hold different types of values(such as string, int, float, DateTime, and bool) by a string key. I could use Hashtable since it is not strongly typed collection class, while the Dictionary is used for strongly typed items (I could use object for Dictionary even though).

Here is the case I would like to define my class and its usage:

 public class MyBaseClass<D> {
   protected Hashtable ht = new Hashtable();

   MyClass public SetValue<T>(string key, T value)
   {
       ht.Add(key, value);
       return this;
   }

   public abstract D GetObject();
 }

 // Example of using the base class for data as class Data1
 public MyClass<Data1> : MyBaseClass<Data1> {
      public Data1 GetObject() {
         return new Data1 {
             Property1 = ht["key1"] as string,
             Property2 = Int.Parse(ht["key2"].ToString())
          }
 }

With above example, I am not sure what is the best collection to hold my data in MyBaseClass? I read some articles about Hashtable. It is an obsolete collection and the performance comparing to Dictionary collection is much slower. Should I use Dictionary or any other collection available in .Net 3.5?

Francis B.
  • 7,018
  • 2
  • 32
  • 54
David.Chu.ca
  • 37,408
  • 63
  • 148
  • 190

5 Answers5

9

Personally I'd use Dictionary<string, object> in this case. At the very least this will stop you from trying to use a non-string key.

I would personally stop using a protected field as well - consider adding an indexer to your base class with a protected setter and a public getter:

public object this[string key]
{
    get { return ht[key]; }
    protected set { ht[key] = value; }
}

If you want it to return null on access by missing key, you should use TryGetValue in the getter. Likewise you could use Add in the setter if you want to fail on duplicate key addition.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • actually in this case, I don't care about null or exception. I would like to get exception in case I try get a value what is not set yet. – David.Chu.ca Sep 16 '09 at 16:04
  • In that case the code I posted would be fine. If you use the same key twice for *setting* it will just overwrite the previous value though. – Jon Skeet Sep 16 '09 at 16:25
  • @Jon Skeet, thank you for your info. I may use this override feature to read another set of properties and then create a new obj based on the new set data. In order words, I can reuse the instance in a loop or method call (loop or method call is kind of repeat with different values). – David.Chu.ca Sep 16 '09 at 17:13
  • What would be the other alternatives to using object? This(object) is pretty poor performance wise, since they have to be boxed/unboxed. This is bringing us back all the way pre generics... – River Apr 24 '12 at 22:33
  • @River: Only value types would need to be boxed/unboxed, of course. As for "pretty poor performance wise" - I'd only worry about that when I had evidence that it was a performance bottleneck. You'd really have to be calling this *very often* for it to be an issue. – Jon Skeet Apr 25 '12 at 05:22
4

You should always use generic collections, unless there is a very good reason not to. This ensures everything is reasonably type safe and reduces programming errors. There are also performance benefits if you store value types in the generic dictionary; if you use Hashtable, each value type would have to be boxed.

Your example, however, seems inherently type-unsafe, and has a code smell about it. Is there a particular reason why you've got two type variables to access the same hashtable?

thecoop
  • 45,220
  • 19
  • 132
  • 189
2

Hashtable existed in 1.1. Dictionary did not exist until generics came in in 2.0. I don't think there's any reason to use Hashtable in 2.0 and beyond - it's essentially a hardcoded Dictionary<string,object> , and it's (probably?) just there to let ported 1.1 code work.

So, Dictionary should be your object of choice here.

quillbreaker
  • 6,119
  • 3
  • 29
  • 47
1

I would use a Dictionary, but I really wanted to make my collection typesafe, I might implement the type-safe heterogeneous container described in Item 29 of Effective Java (the example is for Java, but the application should work for both languages although the details and restrictions may differ). This technique encodes the type of the value into the key.

Kathy Van Stone
  • 25,531
  • 3
  • 32
  • 40
  • Plus 1 for interesting! The original link in your comment is broken, but here is an article on the technique: http://idlebrains.org/tutorials/java-tutorials/effective-java-typesafe-heterogeneous-container-pattern/ Also, here is the book on Amazon: http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683/ref=sr_1_1?ie=UTF8&qid=1410969528&sr=8-1&keywords=effective+java – Bill Sep 17 '14 at 16:02
0

I would go with the Dictionary. I can think of only one scenario where a Hashtable might be preferred. It is thread-safe for one writer and multiple readers without using synchronization mechanisms. But, such a scenario would be very specific and quite rare. And even then I would probably go with the Dictionary and use all of the normal synchronization primitives.

Brian Gideon
  • 47,849
  • 13
  • 107
  • 150