18

Here is my code: An ArrayList of ArrayList that returns a float:

public ArrayList walls=new ArrayList(); 

public void Start()
{
    walls[0] = ReturnInArrayList(279,275,0,0,90);
    walls[1] = ReturnInArrayList(62,275,0,0,0);
    walls[2] = ReturnInArrayList(62,275,62,0,90);
    walls[3] = ReturnInArrayList(217,275,62,-62,0);
    walls[4] = ReturnInArrayList(62,275,279,0,90);
    walls[5] = ReturnInArrayList(41,275,279,0,0);
    walls[6] = ReturnInArrayList(279,275,320,0,9);
    walls[7] = ReturnInArrayList(320,275,0,-279,0); 

    for (int i = 0; i < walls.Length; i++) {
        float a = (float)walls[i][0];
        float b = (float)walls[i][1];
        float c = (float)walls[i][2];
        float d = (float)walls[i][3];
        float e = (float)walls[i][4];
    }
}

ArrayList ReturnInArrayList(float a,float b,float c, float d, float e)
{
    ArrayList arrayList = new ArrayList();
    arrayList.Add(a);
    arrayList.Add(b);
    arrayList.Add(c);
    arrayList.Add(d);
    arrayList.Add(e);
    return arrayList;
}

It gives me the following error:

error CS0021: Cannot apply indexing with [] to an expression of type `object'

I already did the casting, what is wrong? :(

JamesB
  • 569
  • 1
  • 9
  • 31
  • 1
    Does the compiler provide a hint as to where the error might be? – HABO Dec 22 '12 at 16:26
  • I don't see where your code applies indexing to an expression of type object. Do we get a clue? – Jonathan Wood Dec 22 '12 at 16:27
  • 1
    Use classes and add them to a strongly typed `List`. – Tim Schmelter Dec 22 '12 at 16:31
  • 1
    Yes, it provides hint, sorry: All these lines: " float a=(float)paredes[i][0]; float b=(float)paredes[i][1]; float c=(float)paredes[i][2]; float d=(float)paredes[i][3]; float e=(float)paredes[i][4]; " – JamesB Dec 22 '12 at 17:13

4 Answers4

14

The problem is that paredes[i] returns an object which is the return type of the ArrayList indexer. You need to cast this to an ArrayList to be able to access it:

float a= (float)((ArrayList)paredes[i])[0];

A better solution though is to use generics and populate a List<float> instead:

List<float> RetornaEmList(float a,float b,float c, float d, float e)
{
    return new List<float> { a, b, c, d, e };
}

then paredes is a List<List<float>> and your accessor can be changed to:

float a = paredes[i][0];
Lee
  • 142,018
  • 20
  • 234
  • 287
  • 2
    Thanks so much. I was iterating over the rows in a datatable with foreach (var row in dt.Rows) {} and it wasn't recognizing the typical row["ID"]. Once I changed var to DataRow everything worked. – mdegges Jul 20 '18 at 22:03
3

ArrayList stores objects without limiting what type those objects are. When you access the objects stored in an ArrayList, the compiler doesn't know what type they are, so it just gives you type object.

You're storing an ArrayList of float in your outer ArrayList. Since you're always storing floats, it would be better to use a List<float> for the inner list, and a List<List<float>> for the outer list. This way you won't have to type cast from object:

using System.Collections.Generic;

public List<List<float>> paredes = new List<List<float>>();   


Start() {
    paredes[0]=RetornaEmList(279,275,0,0,90);
    paredes[1]=RetornaEmList(62,275,0,0,0);
    paredes[2]=RetornaEmList(62,275,62,0,90);
    paredes[3]=RetornaEmList(217,275,62,-62,0);
    paredes[4]=RetornaEmList(62,275,279,0,90);
    paredes[5]=RetornaEmList(41,275,279,0,0);
    paredes[6]=RetornaEmList(279,275,320,0,9);
    paredes[7]=RetornaEmList(320,275,0,-279,0);    



    for (int i=0;i<paredes.Length;i++)
    {           
        float a=paredes[i][0];
        float b=paredes[i][1];
        float c=paredes[i][2];
        float d=paredes[i][3];
        float e=paredes[i][4];                   
    }
}

List<float> RetornaEmList(float a,float b,float c, float d, float e)
{
    return new List<float> { a, b, c, d, e };
}

Since the inner list always has 5 floats, you could also use a float[] instead of a List<float>

If you just want to make the code work without moving from ArrayList to List, you need an additional cast:

float a = (float)((ArrayList)paredes[i])[0];

But it's a lot cleaner just to use List<float> instead.

Scott Chapman
  • 920
  • 1
  • 7
  • 13
1

Where are you doing the casting?

I would say it must be (did not try with a compiler):

for (int i = 0; i < paredes.Length; i++)
{           
    float a=(float)((ArrayList)paredes[i])[0];
    ...                   
}

Did you consider using the generic collections instead?

public List<List<float>> paredes = new List<List<float>>();   
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
CSharper
  • 524
  • 3
  • 9
0

Code should be like this :

//Adding List

paredes.Add(RetornaEmArrayList(279,275,0,0,90));
paredes.Add(RetornaEmArrayList(62,275,0,0,0));
paredes.Add(RetornaEmArrayList(62,275,62,0,90));
paredes.Add(RetornaEmArrayList(217,275,62,-62,0));
paredes.Add(RetornaEmArrayList(62,275,279,0,90));
paredes.Add(RetornaEmArrayList(41,275,279,0,0));
paredes.Add(RetornaEmArrayList(279,275,320,0,9));
paredes.Add(RetornaEmArrayList(320,275,0,-279,0));


//Traversing List

foreach(ArrayList item in paredes)
{
    float a=(float)item[0];
    float b=(float)item[1];
    float c=(float)item[2];
    float d=(float)item[3];
    float e=(float)item[4];
}
Kundan Singh Chouhan
  • 13,952
  • 4
  • 27
  • 32