Подтвердить что ты не робот

Casting system.array object to int [] string или другие объекты типа

Я изучаю С# и пытаюсь понять его "ориентированные на тип" аспекты.

Итак, на днях мне нужно было получить объект System.Array из метода. Затем я попытался работать с ним с отдельными объектами, поэтому я попытался обратиться к нему с индексом. Компилятор не позволил мне сказать, что объект System.Array не поддерживает индексирование.

Но не является ли Array базовым классом для всех массивов (System.Array на msdn)? Как этот int [] поддерживает индексирование, а Array [] не работает?

вот какой код для демонстрации проблемы:

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

Итак, у нас есть 2 объекта, которые, похоже, одного типа. Но один реализует индексирование, а другой - нет, как это возможно?


ссылка на ответы

прочитав ваши комментарии, я думаю, что у меня есть смысл. int [] и массив объектов. каждый из объектов является структурой типа int32. Массив [] - массив объектов. каждый из объектов является классом типа Array. значение: массив массивов. как я могу отобразить в следующем коде:

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

и так далее... поэтому я понял, почему способ, которым я пытался получить доступ к элементам sysArray, был неправильным. intArray → 1 массив из многих ints sysArray → 1 класс (который предоставляет доступ ко многим ints)

с точки зрения языка sysArray вообще не является массивом, это всего лишь ссылка на 1 объект (типа System.Array)

(извините за повторение бит, но это действительно помогает установить что-то в моей голове)

Благодарю всех вас за руководство в понимании этой разницы.

относительно решений.. что я искал и работал у меня лучше всего:

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

Ответ 1

Кастинг позаботится о разнице:

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

Вы видите, что оба массива имеют тип System.Int32[], потому что они (вот почему это работает).

Ответ 2

int объявляется как struct в BCL

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

Пока Array объявляется следующим образом:

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

Таким образом, они на самом деле не совпадают.

Если вы хотите получить элементы из массива с помощью индексатора, я думаю, вам нужно будет сделать это:

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

Причина объясняется тем, как объявлен метод указателя в массиве:

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

Так как IList объявляется в сигнатуре, это означает, что вам нужно будет отбросить sysArray в IList<int>, чтобы получить доступ к индексу. Если вместо этого указатель был объявлен следующим образом:

Object this[int index] {

тогда да, вы могли бы сделать sysArray[0]; без проблем.

Ответ 3

Вы должны посмотреть интерфейсы, которые реализует каждый объект. Array реализует System.Collections.IList, который предоставляет индексный объект, а int не предоставляет реализацию IList.

Ответ 4

System.Array - абстрактный базовый класс. Документация microsoft говорит все это...

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 не предоставляет реализацию индексатора.

Что будет работать для вас, это...

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

Ответ 5

Предполагая, что eventTypes - это объекты, содержащие целые значения (object[] eventTypes):

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

Ответ 6

Вы можете прочитать значения массива с помощью функции GetValue.

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