Casting Hashtable as ArrayList

Hi,

Having a little problem with this code below. It errors when I try to use the positions array I've casted and when I use (htFields[field] as ArrayList).Add(i);.

Thanks for reading and for your help.

---

       private void loadDescriptors(string descriptor)
        {
            Hashtable htFields = new Hashtable();
            ArrayList alFields = new ArrayList();

            int i = 0;
            int basePtr = pointers.getPointer(descriptor);
            while (true)
            {
                int ptr = memory.ReadInteger(basePtr);

                if ((ptr & 0x40000000) == 0x40000000)
                    break;

                string field = memory.ReadString(ptr, 64);

                if (field == "OBJECT_FIELD_GUID" && i > 2)
                    break;

                if (!htFields.ContainsKey(field))
                    htFields.Add(field, i * 4);

                // Exception: Object not set to a reference of an instance
                (htFields[field] as ArrayList).Add(i);
                alFields.Add(field);

                basePtr += 0x14;
                i++;
            }

            Console.WriteLine("public class " + descriptor);
            Console.WriteLine("{");
            foreach (string field in alFields)
            {
                if (htFields.ContainsKey(field))
                {
                    ArrayList positions = (ArrayList)htFields[field];

                    Console.Write("\tpublic static int[] " + field + " = {");

                    // Exception when using 'positions'
                    for (i = 0; i < positions.Count; i++)
                    {
                        if (i > 0)
                            Console.Write(",");

                        if (i % 5 == 0 && positions.Count > 2)
                        {
                            Console.WriteLine("");
                            Console.Write("\t\t\t");
                        }

                        Console.Write("0x" + ((int)positions[i] * 4).ToString("X"));
                    }
                    Console.WriteLine("};");

                    htFields.Remove(field);
                }
            }
            Console.WriteLine("};");
        }
valvetAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AGBrownCommented:
When you add to your arraylist, it looks like you are using
htFields.Add(field, i * 4);
This is adding an integer multiplied by 4. Then you do
((ArrayList)htFields[field]) - except this cast is invalid, as you have an integer instead of an arraylist.

Would:
htFields.Add(field, new ArrayList(i * 4));
be more appropriate?

Andy
0
valvetAuthor Commented:
Oh, yeah. I was wondering why I got an int error if I moved it around hehe.

I do get a duplicate entry somewhere.. perhaps you can help me find that too? :-)

        private Hashtable loadDescriptors(string descriptor)
        {
            Hashtable htFields = new Hashtable();
            ArrayList alFields = new ArrayList();

            int i = 0;
            int basePtr = owner.pointers.getPointer(descriptor);
            while (true)
            {
                int ptr = owner.Memory.ReadInteger(basePtr);

                if ((ptr & 0x40000000) == 0x40000000)
                    break;

                string field = owner.Memory.ReadString(ptr, 64);

                if (field == "OBJECT_FIELD_GUID" && i > 2)
                    break;

                if (!htFields.ContainsKey(field))
                    htFields.Add(field, i * 4);

                //(htFields[field] as ArrayList).Add(i);
                htFields.Add(field, new ArrayList(i * 4));
                alFields.Add(field);

                basePtr += 0x14;
                i++;
            }


            Console.WriteLine("public class " + descriptor);
            Console.WriteLine("{");
            foreach (string field in alFields)
            {
                if (htFields.ContainsKey(field))
                {
                    ArrayList positions = (ArrayList)htFields[field];

                    Console.Write("\tpublic static int[] " + field + " = {");
                    for (i = 0; i < positions.Count; i++)
                    {
                        if (i > 0)
                            Console.Write(",");

                        if (i % 5 == 0 && positions.Count > 2)
                        {
                            Console.WriteLine("");
                            Console.Write("\t\t\t");
                        }

                        Console.Write("0x" + ((int)positions[i] * 4).ToString("X"));
                    }
                    Console.WriteLine("};");

                    htFields.Remove(field);
                }
            }

            Console.WriteLine("};");

            return htFields;
        }


"Item has already been added. Key in dictionary: '&#9644;'  Key being added: '&#9644;'"

I wish the errors could be a little more specific hehe. Throw new Exception(HoldUsersHandAndPointToLine)

Cheers :-)
0
AGBrownCommented:
So now you have this:

      if (!htFields.ContainsKey(field))
      htFields.Add(field, i * 4);

      //(htFields[field] as ArrayList).Add(i);
      htFields.Add(field, new ArrayList(i * 4));
      alFields.Add(field);

And I think you need:

      if (!htFields.ContainsKey(field))
      {
            //htFields.Add(field, i * 4); // <-------- got rid of this line

            // <---------------- put these lines inside the block that tests for existence in the hashtable
            // <---------------- otherwise will get duplicate entry in hashtable
            //(htFields[field] as ArrayList).Add(i);
            htFields.Add(field, new ArrayList(i * 4));
            alFields.Add(field);
      }
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

valvetAuthor Commented:
Thanks alot! That appears to have worked.. to some extent. Think I can manage from here ;-).

Cheers.
0
valvetAuthor Commented:
Sorry to bother you again :-)...

I'm a bit puzzled as to why:

ArrayList positions = (ArrayList)htFields[field];

.Count keeps returning 0 and there for the for loop never get's executed..
0
valvetAuthor Commented:
Other than that, the rest is outputting fine

ArrayList positions = (ArrayList)htFields[field];
Console.WriteLine("Count: {0}", positions.Count);

--

public static int[] DYNAMICOBJECT_BYTES = {};
Count: 0
0
AGBrownCommented:
Count will be zero if you haven't added any items to the arraylist, which I think you haven't as when you add the arraylist to the hashtable you only set it's capacity, you don't add any items.

Try .Capacity instead for your loop and see if that helps.
0
valvetAuthor Commented:
Ok now it outputtet 8 as Capacity..

Index was out of range. Must be non-negative and less than the size of the colle
ction.

Strange, but there's something in the position's array. I shall try a foreach loop
0
valvetAuthor Commented:
Hmm, nope. No output.. that's odd.
0
AGBrownCommented:
Well, if you are going with the code you posted starting "Oh, yeah. I was wondering why I ..." then you haven't actually put any entries into the arraylist, so it won't give you anything, and you will get that error.

Capacity is not always set to what you set it to - it is set to optimal values that .NET decides on.

You need to, in your first loop, put something into each position in the arraylist after you have instantiated it and put it in the hashtable, otherwise it will be empty. So after your

     if (!htFields.ContainsKey(field))
     {
          //htFields.Add(field, i * 4); // <-------- got rid of this line

          // <---------------- put these lines inside the block that tests for existence in the hashtable
          // <---------------- otherwise will get duplicate entry in hashtable
          //(htFields[field] as ArrayList).Add(i);
          htFields.Add(field, new ArrayList(i * 4));
          alFields.Add(field);
     }
you need to fill the arraylist with some values.
0
valvetAuthor Commented:
Ah, alright. I'll play around with that, thanks again :-).
0
AGBrownCommented:
Good luck. I'm off for the night now, so if you have any more questions I would put them in a fresh question.

A.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.