The introduction of Portable Class Libraries, PCL, considerably facilitates the sharing of functionality across managed Microsoft and Xamarin platforms. I am very enthusiastic about the PCL concept, and I have ported several .NET Framework open source projects to Portable Class Libraries. Along the way I have stumbled across various issues of making .NET Framework source code PCL compliant. In this mini-series I'll share my experiences and workarounds to facilitate the transfer to PCL for other developers.
C# code that has its roots in pre-generic time (.NET Framework 1.x, that is) often tend to contain non-generic collections such as ArrayList and Hashtable. In the Portable Class Libraries however, non-generic collections are avoided to the largest possible extent, and Hashtable is one of the missing classes.
Hashtable is simply a non-generic dictionary (it implements IDictionary) and it also shares the main methods and properties with the generic Dictionary<TKey, TValue> class, which is available across all PCL profiles.
It is thus actually quite straightforward to replace all Hashtable instances with Dictionary<TKey, TValue> instances. And as an added benefit, the dictionary can often be specialized as well, i.e. instead of replacing Hashtable with Dictionary<object, object> you can apply the actual key and value types.
Here is one example from the CSJ2K project, which is a C# class library for JPEG2000 encoding and decoding. In the .NET Framework-only project on Codeplex, in the ChannelDefinitionBox class, the field definitions is declared as a Hashtable where int is always used as keys and int as values.So, in my PCL adaptation of the CSJ2K project on Github, I have happily replaced Hashtable with Dictionary<int, int> in the adapted ChannelDefinitionBox class.
One additional comment is in place: in the aforementioned project CSJ2K, the hash tables are consistently created using the Synchronized method to ensure that the hash table is thread-safe. Dictionary<TKey, TValue> on the other hand does not guarantee thread-safety. A solution to this problem would be to instead use ConcurrentDictionary<TKey, TValue>, but this specialized dictionary is available in substantially fewer PCL profiles. If your PCL is targeting Windows Phone 8 or earlier, or Silverlight for that matter, ConcurrentDictionary will not be available. There is another workaround to this issue, but I'll save that for a subsequent post...