Ответ 1
Кастинг позаботится о разнице:
t = (sysArray as int[])[4];
Вы видите, что оба массива имеют тип System.Int32[]
, потому что они (вот почему это работает).
Я изучаю С# и пытаюсь понять его "ориентированные на тип" аспекты.
Итак, на днях мне нужно было получить объект 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];
Кастинг позаботится о разнице:
t = (sysArray as int[])[4];
Вы видите, что оба массива имеют тип System.Int32[]
, потому что они (вот почему это работает).
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];
без проблем.
Вы должны посмотреть интерфейсы, которые реализует каждый объект. Array
реализует System.Collections.IList
, который предоставляет индексный объект, а int
не предоставляет реализацию IList
.
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);
Предполагая, что eventTypes
- это объекты, содержащие целые значения (object[] eventTypes
):
int[] eventTypeIDs = eventTypes.Select(Convert.ToInt32).ToArray();
Вы можете прочитать значения массива с помощью функции GetValue.
array.GetValue(1);
array.GetValue(1,2);