2011-12-30 11 views
12

Estoy aprendiendo C# y tratando de entender los aspectos "orientados a tipo" de la misma.casting system.array object to int [] cadena u objetos de otro tipo

Así que el otro día necesitaba recibir un objeto System.Array de un método. Luego traté de trabajar con sus objetos individuales, así que traté de abordarlo con un índice. El compilador no me lo permitió, diciendo que el objeto System.Array no es compatible con la indexación.

Pero no es Array es la clase base para todas las matrices (System.Array on msdn)? ¿Cómo es que int [] admite la indexación y Array [] no?

Aquí hay un código para demostrar el problema:

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 

Así que lo que tenemos aquí es de 2 objetos, que parecen ser del mismo tipo. Pero uno está implementando indexación y el otro no, ¿cómo es posible?


una referencia a las respuestas

después de leer sus comentarios Creo que tengo el sentido de las cosas. int [] es una matriz de objetos. cada uno de los objetos es una estructura de tipo int32. Array [] es una matriz de objetos. cada uno de los objetos es una clase de tipo Array. significado: una matriz de matrices. que puedo mostrar en el siguiente código:

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); 

y así sucesivamente ... por lo que entiende por qué la forma en que trató de acceder a los elementos de sysArray estaba mal. intArray -> 1 arreglo de muchos enteros sysArray -> 1 clase (que permite el acceso a muchos enteros)

desde el punto de vista sysArray de la lengua no es una matriz en absoluto, es sólo una referencia a 1 objeto (tipo de System.array)

(lo siento por repetir un poco, pero realmente ayuda a establecer las cosas en mi cabeza)

gracias a todos por guía en la comprensión de esa diferencia.

con respecto a las soluciones .. que lo que estaba buscando y me funcionó mejor:

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];  
+0

Tu pregunta no está clara. Un int es un objeto .... Entonces, lo que estás haciendo tiene poco sentido. –

Respuesta

11

casting se hará cargo de la diferencia:

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

Usted está viendo que ambas matrices son de tipo System.Int32[], porque son (que es por lo que este elenco funciona).

5

int se declara como struct en el BCL

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

Mientras Array se declara como tal :

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

Entonces, en realidad no son lo mismo.

Si desea obtener artículos de matriz mediante un indexador, creo que tendrá que hacer esto:

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

La razón es debido a cómo se declara el método paso a paso en Array:

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

Dado que IList se declara en la firma, significa que deberá convertir sysArray en IList<int> para acceder al indexador. Si, en cambio, el indexador había sido declarado como esto:

Object this[int index] { 

entonces sí, se puede hacer sysArray[0]; sin ningún problema.

+0

Una vez más, el OP no pregunta por qué un solo 'int' no puede ser indexado. Se preguntan por qué un objeto genérico 'System.Array' no puede ser indexado. –

+0

Al usar 'int []', en realidad está usando una construcción de lenguaje C#, es decir, matrices. Eso significa que hay soporte integrado para acceder a índices, p. 'myarray [23];'. En esencia, accedes a una serie de 'estructuras' (int) La clase' Array' es un objeto en sí mismo, y cuando usas acceso de índice en él, no estás usando el lenguaje C#, sino que estás usando lo que sea El método indizador está en esa clase, es decir, 'Objeto IList.this [int index]'. Entonces, en pocas palabras, los métodos de acceso de índice para cada tipo son totalmente diferentes. –

+0

No creo que las matrices sean una "construcción de lenguaje C#". El uso de corchetes para la indexación de elementos de matriz es una construcción de lenguaje ... la existencia de matrices es una característica fundamental de la CLI. Consulte ** ECMA-335: 8.9.1 Tipos de matriz **. En cuanto a IList, incluye (como usted nota) el indexador 'this [int index]'. Entonces, ¿cómo System.Array puede implementar IList sin implementar el miembro requerido 'this [int index]'? –

1

Tiene que observar las interfaces que cada objeto implementa. Array implementa System.Collections.IList que proporciona un indexador de objetos, mientras que int no proporciona una implementación IList.

+1

Eso no es lo que implica el OP. El OP pregunta por qué la clase abstracta System.Array no permite el acceso a los elementos mediante la sintaxis del indexador: es la expresión 'sysarray [4]' que bombs. –

1

System.Array es una clase base abstracta. La documentación de Microsoft lo dice todo ...

Provides methods for creating, manipulating, searching, and sorting arrays, thereby 
serving as the base class for all arrays in the common language runtime. 

System.Array no proporciona una implementación para el indexador.

Lo que funciona para usted es esta ...

int[] sysArray = (int[])Array.CreateInstance(typeof(int), 10); 
1

Suponiendo eventTypes son objetos que contienen valores enteros (object[] eventTypes):

int[] eventTypeIDs = eventTypes.Select(Convert.ToInt32).ToArray(); 
0

se puede leer los valores de la matriz mediante el uso de la función GetValue.

array.GetValue(1); 
array.GetValue(1,2);