10

I am trying to use someone else's C# classes in my Windows 7 Phone app. The classes use objects of type Hashtable.

The file in question has

using System.Collections;

at the top, so I'm assuming that's the Hashtable object it wants.

When I try to build my solution, I get errors that the type or namespace name 'Hashtable' could not be found, are you missing a using directive or assembly reference.

In Microsoft's documentation of Hashtable, I see it says Assembly: mscorlib

But if I try to add mscorlib via Project>Add Reference, VS says it can't add it because it is automatically referenced by the build system.

What am I missing?

jv42
  • 8,521
  • 5
  • 40
  • 64
William Jockusch
  • 26,513
  • 49
  • 182
  • 323

5 Answers5

27

The non-generic collections, including ArrayList and HashTable, are not included in Silverlight.
These classes are hold-overs from .Net 1.0 (which didn't have generics) and should not be used in new code.

Instead, you should use the generic collections—List<T> and Dictionary<TKey, TValue>.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
10

You have a few options:

  1. Change your import to using System.Collections.Generic; and change every use of a HashTable to Dictionary<> and ArrayList to List<>.

  2. You might be able to get away with:

    using HashTable = System.Collections.Generic.Dictionary<object, object>;
    using ArrayList = System.Collections.Generic.List<object>;
    Note that any future maintainer will hate you for doing this.

  3. But it's better to refactor the code to use the generic collections properly.

  4. Create a class Hashtable in a namespace System.Collections, implement IDictionary<object, object> by forwarding everything to an inner Dictionary<object, object> and implement the necessary changes in behavior (locking, missing keys, etc.); Create an ArrayList by encapsulation List<object>. (suggested by henon)

Community
  • 1
  • 1
Gabe
  • 84,912
  • 12
  • 139
  • 238
  • #2 is a horrible idea. It would work, though, except that you need fully-qualified typenames. – SLaks Feb 16 '11 at 00:35
  • @SLaks: You might not have noticed, but I have 3 ideas. Which one's horrible? Also, I'm not sure what you mean needs to be fully qualified. – Gabe Feb 16 '11 at 01:24
  • The `using` statements need fully-qualified typenames, unless placed separately inside the `namespace`. – SLaks Feb 16 '11 at 01:26
  • SLkaks: Good point. It's almost certainly the case that code old enough to use the old collection classes would have the `using` list outside the `namespace`. – Gabe Feb 16 '11 at 01:31
  • 2
    +1 for the abominable #2 suggestion and then pointing out that anyone looking at it in the future may well wish you eviscerated – ctacke Feb 16 '11 at 02:14
  • Idea #4 that works very well: create a class Hashtable in a namespace System.Collections, implement IDictionary by forwarding everything to an inner Dictionary and implement the indexer so that it does not fail when the key is not present in the inner dict. – henon Nov 27 '12 at 13:27
2

There are different mscorlibs depending on which .NET framework you are using. If you look in the "Other Versions" dropdown on the MSDN page, you will see Hashtable is not a part of Silverlight. You will need to use a Dictionary<Object, Object> (or ideally more strongly typed keys and value types)

Hashtable is not in Silverlight

But Dictionary is

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
1

System.Collection is a legacy of first version of .Net - no generic types.

To fix your code use Dictorany class which is a hashtable at heart, and List insted of ArrayList.

Lukasz Madon
  • 14,664
  • 14
  • 64
  • 108
0

It worked for me changing:

Hashtable for Dictionary<object, object>

NameValueCollection for Dictionary<object, object>

Other problem I encoutered is Encoding.ASCII is not defined either, I sorted that with a function a stackoverflow lad wrote:

public static byte[] StringToAscii(string s) {
    byte[] retval = new byte[s.Length];
    for (int ix = 0; ix < s.Length; ++ix) {
        char ch = s[ix];
        if (ch <= 0x7f) retval[ix] = (byte)ch;
        else retval[ix] = (byte)'?';
    }
    return retval;
}

credits here:

ASCIIEncoding In Windows Phone 7

So finally to return the ASCII this is what to do:

return StringToAscii(Encoding.Unicode.GetString(result.ToArray()));

Community
  • 1
  • 1
Alfonso Leon
  • 497
  • 4
  • 4