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];
It only works for arrays of reference types. Arrays of value types are a physically different size, so this cannot work.
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.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With