【问题标题】:casting system.array object to int[] string or other type's objects将 system.array 对象转换为 int[] 字符串或其他类型的对象
【发布时间】:2012-01-30 15:03:09
【问题描述】:

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

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

但是 Array 不是所有数组的基类 (System.Array on 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 个对象,它们似乎属于同一类型。 但是一个在实现索引,另一个没有,怎么可能?


对回复的引用

在阅读了您的 cmets 之后,我想我明白了。 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];    

【问题讨论】:

  • 您的问题不清楚。一个 int 是一个对象......所以你所做的没有什么意义。
  • 好问题。表明 System.Array 毕竟不只是一个数组......这个世界将走向何方?

标签: c# system.array


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      intBCL 中声明为struct

      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 转换为IList&lt;int&gt; 才能访问索引器。相反,如果索引器是这样声明的:

      Object this[int index] {
      

      那么是的,您可以毫无问题地使用sysArray[0];

      【讨论】:

      • 再次,OP 并没有问为什么单个 int 不能被索引。他们在问为什么不能索引一个通用的System.Array 对象。
      • 当使用 int[] 时,您实际上是在使用 C# 语言结构,即数组。这意味着有对索引访问的内置支持,例如myarray[23];。本质上,您访问的数组 structs (int) 类 Array 本身就是一个对象,因此在对其使用索引访问时,您不是在使用 C# 语言,而是在使用任何索引器方法在那个类上,即Object IList.this[int index]。所以简而言之,每种类型的索引访问器方法是完全不同的。
      • 我不认为数组是“C# 语言结构”。使用方括号进行数组元素索引是一种语言结构……数组的存在是 CLI 的基本特征。请参阅 ECMA-335:8.9.1 数组类型。至于 IList,它包括(如您所见)索引器 this[int index]。那么System.Array如何在不实现所需成员this[int index]的情况下实现IList呢?
      • 嗯,我知道你打算用这个去哪里。问题是Array 通过Object IList.this[int index] 实现了它的索引器。如果它被声明为Object this[int index],那么您可以毫无问题地执行sysArray[0]。但是因为IList 是在签名中声明的,所以会有所不同,并导致我们必须强制转换sysArray 才能访问它的索引器。我认为最终的问题是为什么要打扰 Array 类?
      • 谢谢你们,你们的例子和讨论实际上帮助我理解了 sysArray 的真正含义。 @JasonEvans
      【解决方案4】:

      铸造将处理差异:

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

      您会看到两个数组都是System.Int32[] 类型,因为它们是(这就是这种强制转换起作用的原因)。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          您必须查看每个对象实现的接口。 Array 实现了 System.Collections.IList,它提供了一个对象索引器,而 int 不提供 IList 实现。

          【讨论】:

          • 这不是 OP 所暗示的。 OP 询问为什么抽象 System.Array 类不允许使用索引器语法访问元素:这是表达式 sysarray[4] 炸弹。
          猜你喜欢
          • 2012-01-16
          • 1970-01-01
          • 1970-01-01
          • 2017-02-07
          • 2022-01-19
          • 2011-10-02
          • 1970-01-01
          • 1970-01-01
          • 2022-01-20
          相关资源
          最近更新 更多