приведение объекта system.array к строке int [] или объектам другого типа - PullRequest
13 голосов
/ 30 декабря 2011

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

Поэтому на днях мне нужно было получить объект 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 массив из множества целых sysArray -> 1 класс (который предоставляет доступ ко многим целым числам)

с точки зрения языка 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];    

Ответы [ 6 ]

12 голосов
/ 30 декабря 2011

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

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

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

5 голосов
/ 30 декабря 2011

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]; без проблем.

1 голос
/ 27 июня 2013

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

int[] eventTypeIDs = eventTypes.Select(Convert.ToInt32).ToArray();
1 голос
/ 30 декабря 2011

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);
1 голос
/ 30 декабря 2011

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

0 голосов
/ 21 августа 2013

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

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