Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

casting system.array object to int[] string or other type's objects

I am learning c# and trying to understand the "type oriented" aspects of it.

So the other day I needed to receive an System.Array object from a method. Then I tried to work with it's individual objects, so i tried to address it with an index. Compiler wouldn't let me, saying that System.Array object do not support indexing.

But isn't Array is the base class to all arrays (System.Array on msdn)? How is that int[] supports indexing and Array[] doesn't?

here is some code to demonstrate the problem:

int[] intArray = {1,2,3,4,5,6,7,8,9,10};
int t;
Array sysArray;       
Console.WriteLine("{0}", intArray.GetType().ToString()); // output: System.Int32[]
sysArray = Array.CreateInstance(typeof(int), 10);
Console.WriteLine("{0}", sysArray.GetType().ToString()); // output: System.Int32[]
sysArray = intArray; //compiles ok
//t = sysArray[4]; This line produces error Error 2 Cannot apply indexing with [] to an
// expression of type 'System.Array'
//t = intArray[4]; This line compiles ok

So what we have here is 2 objects, that seem to be of the same type. But one is implementing indexing and the other is not, how is it possible?


a reference to the replies

after reading your comments i think i got the sense of things. int[] is and array of objects. each of the objects is a struct of type int32. Array[] is an array of objects. each of the objects is a class of type Array. meaning : an array of arrays. as i can display in the following code:

Array[] sysArrayOfArray = new Array[SIZE_OF_THE_MOTHER_ARRAY];
sysArrayOfArray[0] = Array.CreateInstance(typeof(int),SIZE_OF_FIRST_CHILD_ARRAY);
sysArrayOfArray[1] = Array.CreateInstance(typeof(int),SIZE_OF_FIRST_SECOND_ARRAY);

and so on... so I understood why the way i tried to access the elements of sysArray was wrong. intArray -> 1 array of many ints sysArray -> 1 class (which grants access to many ints)

from the language's point of view sysArray is not an Array at all, it is only a reference to 1 object (of type System.Array)

(sorry for repeating a bit, but it really helps set things in my head)

thank you all for guiding in understanding that difference.

regarding the solutions.. that what i was looking for and worked for me best:

 Array sysArray = Array.CreateInstance(typeof(int),3);
 int[] intArray = new int[3];
 int one, ten, hundred;
 sysArray.SetValue(1, 0);
 sysArray.SetValue(10,1);
 sysArray.SetValue(100,2);
 intArray = (int[])sysArray;// works, but forces me to create a new reference
 one = ((int[])sysArray)[0];// works and is exactly what i was looking for...
 ten = ((int[])sysArray)[1];
 hundred = ((int[])sysArray)[2];    
like image 520
Eliy Arlev Avatar asked Dec 30 '11 14:12

Eliy Arlev


People also ask

Can we assign integer array to object array in C#?

It only works for arrays of reference types. Arrays of value types are a physically different size, so this cannot work.

How do you change an object to an array in Java?

Core Java bootcamp program with Hands on practice toArray() returns an Object[], it can be converted to String array by passing the String[] as parameter.


2 Answers

Casting will take care of the difference:

    t = (sysArray as int[])[4];

You are seeing that both arrays are of type System.Int32[], because they are (which is why this cast works).

like image 124
Mark Avenius Avatar answered Sep 19 '22 19:09

Mark Avenius


int is declared as a struct in the BCL

public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<Int32>, Equatable<Int32> 

Whilst Array is declared like so:

public abstract class Array : ICloneable, IList, IStructuralComparable, IStructuralEquatable

So they are not actually the same.

If you do want to get items from Array using an indexer, I think you will need to do this:

int number = ((IList<int>)sysArray)[4];

The reason is due to how the indexer method is declared in Array:

Object IList.this[int index] { 
  get { return GetValue(index); }
  set { SetValue(value, index); } 
}

Since IList is declared in the signature, it means that you will need to cast sysArray into a IList<int> in order to access the indexer. If, instead, the indexer had been declared like this:

Object this[int index] {

then yes, you could do sysArray[0]; without any problems.

like image 21
Jason Evans Avatar answered Sep 18 '22 19:09

Jason Evans