15

我正在学习 c# 并试图理解它的“面向类型”方面。

所以前几天我需要从一个方法接收一个 System.Array 对象。然后我尝试使用它的单个对象,所以我尝试用索引来解决它。编译器不让我说 System.Array 对象不支持索引。

但是 Array 不是所有数组的基类(msdn 上的 System.Array)吗?那 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 类型的类。含义:数组数组。正如我可以在以下代码中显示的那样:

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

6 回答 6

14

铸造将处理差异:

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

您会看到两个数组都是 type System.Int32[],因为它们是(这就是这个演员表起作用的原因)。

于 2011-12-30T15:07:06.783 回答
5

intstruct在_BCL

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

虽然Array声明如下:

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

所以它们实际上并不相同。

如果您确实想使用索引器从 Array 中获取项目,我认为您需要这样做:

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

原因在于 Array 中如何声明 indexer 方法:

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

由于IList在签名中声明,这意味着您需要sysArray转换为 aIList<int>才能访问索引器。相反,如果索引器是这样声明的:

Object this[int index] {

那么是的,你可以sysArray[0];毫无问题地做。

于 2011-12-30T14:59:45.540 回答
1

假设eventTypes对象包含整数值 ( object[] eventTypes):

int[] eventTypeIDs = eventTypes.Select(Convert.ToInt32).ToArray();
于 2013-06-26T20:43:34.760 回答
1

System.Array 是一个抽象基类。微软文档说明了一切......

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);
于 2011-12-30T15:07:00.357 回答
1

您必须查看每个对象实现的接口。提供对象索引器但不提供实现的Arrayimplements 。System.Collections.IListintIList

于 2011-12-30T15:00:52.780 回答
0

您可以使用 GetValue 函数读取 Array 的值。

array.GetValue(1);
array.GetValue(1,2);
于 2013-08-21T12:41:36.653 回答