Domanda casting dell'oggetto system.array su int [] stringa o altri oggetti del tipo


Sto imparando c # e sto cercando di capire gli aspetti "orientati al tipo" di esso.

Quindi l'altro giorno avevo bisogno di ricevere un oggetto System.Array da un metodo. Poi ho provato a lavorare con i singoli oggetti, quindi ho provato ad affrontarlo con un indice. Il compilatore non mi ha permesso di dire che l'oggetto System.Array non supporta l'indicizzazione.

Ma non è Array è la classe base per tutti gli array (System.Array su msdn)? In che modo int [] supporta l'indicizzazione e l'array [] no?

ecco un codice per dimostrare il 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

Quindi quello che abbiamo qui sono 2 oggetti, che sembrano essere dello stesso tipo. Ma uno sta implementando l'indicizzazione e l'altro no, come è possibile?


un riferimento alle risposte

dopo aver letto i tuoi commenti penso di aver capito il senso delle cose. int [] è e matrice di oggetti. ognuno degli oggetti è una struttura di tipo int32. Array [] è una matrice di oggetti. ognuno degli oggetti è una classe di tipo Array. significato: una matrice di matrici. come posso visualizzare nel seguente codice:

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

e così via... quindi ho capito perché il modo in cui ho provato ad accedere agli elementi di sysArray era sbagliato. intArray -> 1 array di molti ints sysArray -> 1 class (che garantisce l'accesso a molti ints)

dal punto di vista della lingua sysArray non è affatto una matrice, è solo un riferimento a 1 oggetto (di tipo System.Array)

(scusa se ripeto un po ', ma aiuta davvero a sistemare le cose nella mia testa)

grazie a tutti per aver guidato a capire questa differenza.

per quanto riguarda le soluzioni .. quello che stavo cercando e ha funzionato per me al meglio:

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

13
2017-12-30 14:51


origine


risposte:


La fusione si prenderà cura della differenza:

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

Stai vedendo che entrambi gli array sono di tipo System.Int32[], perché sono (che è il motivo per cui questo cast funziona).


12
2017-12-30 15:07



int è dichiarato come a struct nel BCL

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

Mentre Array è dichiarato così:

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

Quindi non sono in realtà la stessa cosa.

Se vuoi ottenere elementi dalla matrice usando un indicizzatore, penso che dovrai fare questo:

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

Il motivo è dovuto al modo in cui il metodo dell'indicizzatore è dichiarato nell'array:

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

Da IList è dichiarato nella firma, significa che dovrai lanciare sysArray in un IList<int> per accedere all'indicizzatore. Se, invece, l'indicizzatore fosse stato dichiarato in questo modo:

Object this[int index] {

allora sì, potresti farlo sysArray[0]; senza alcun problema.


5
2017-12-30 14:59



Devi guardare le interfacce che ogni oggetto implementa. Array attrezzi System.Collections.IList che fornisce un indicizzatore di oggetti mentre int non fornisce un IList implementazione.


1
2017-12-30 15:00



System.Array è una classe base astratta. La documentazione di Microsoft dice tutto ...

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 non fornisce un'implementazione per l'indicizzatore.

Ciò che funzionerà per te è questo ...

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

1
2017-12-30 15:07



assumendo eventTypes sono oggetti contenenti valori interi (object[] eventTypes):

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

1
2018-06-26 20:43



È possibile leggere i valori di Array utilizzando la funzione GetValue.

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

0
2017-08-21 12:41