您如何称呼C#中数组引入的多态性?

时间:2014-04-27 10:39:46

标签: c# .net arrays oop polymorphism

基础架构(CLI / .Net / Mono)级别的AFAIK只有一种类型来表示数组:System.Array

从物理上讲,这是一个线性的值序列,但从逻辑上讲,它们可以被视为多个维度。

在语言层面(例如C#),这种逻辑观点可以从一些语法糖中获益:

2D: T[,]
3D: T[,,]
42D: T[,,,...,,,]

在一维数组后面有一个明显的参数多态,例如可以隐藏多种类型的数组:

Array of integers: int[]
Array of strings references: string[]
Array of objects references: object[]

但是你如何描述结构多态,这个数组可以有多个维度呢?

在基础架构级别,这不再是类型系统的一部分,只是一个逻辑视图,所以我认为根本没有多态性。

但在语言层面,它可能被视为某种包含多态,因为所有数组在逻辑上都是从公共基类继承的不同类型。

欢迎任何输入和更正。

3 个答案:

答案 0 :(得分:2)

System.Array类具有基本上无限的导数族,每个元素类型和可能的维数。因为数组早于泛型,所以它们有一个特殊的&#34;准硬编码&#34;实现这一目标的手段。基本上,.NET Framework包含一个特殊的硬编码&#34;配方&#34;因此,给定基础项类型和多个维度,它可以生成从System.Array派生的类型,该类型将充当具有指定的基本项类型和维度的数组。此外,由于数组协方差的工作方式,数组的行为就像它们实现的接口实际上不是它们的类的一部分,其他类型的方式也是如此。例如,因为Cat[]类型的引用也是Animal[]类型的引用,Cat[]不仅会实现IList<Cat>,还会实现IList<Animal>

System.Array以外的任何类型都不支持这种协方差的机制,用户代码也没有任何方法可以定义一个类族,这样对于任何整数n都会有是get方法需要n个参数的衍生工具。 .NET中的泛型类型可以执行许多数组无法做到的事情,但由于数组是通过通用类型工具以外的机制实现的,因此它们可以支持某些设施无法实现的功能。

答案 1 :(得分:1)

所有派生数组类型都来自System.Array并覆盖适当的方法。但是,在 CLR 中以 IL操作码的形式存在与直接与具体数组类型直接交互的烘焙支持的意义上,数组有点特殊。但是,这仍然是与其他类相同的基类多态,至少在通过Array类访问时是这样。

然而,阵列实际上并不是多态的&#39;在你正在思考的意义上的维度。特定的数组实例在构造时会被赋予特定的维度,并且只能与该维度一起使用。这在操作码级别和GetValue方法中都会发生。 “物品”的IList实施&#39; (索引器)也只支持单个维度;如果你试图在多维数组上使用它,你将得到一个ArgumentException。


另外,如果不清楚,A[x,y]语法实际上不是语法糖。实际上,多维数组从内置CLR支持中排除,而是通过方法访问。这编译成类似下面的IL:

Ldloc A //(load array A onto the operation stack)
Ldloc x //(load value of variable x onto the operation stack)
Ldloc y //(load value of variable y onto the operation stack)
call int32[,]::Get(int, int) //(return a 4-byte signed integer from the array at indices [x,y], putting the result onto the operation stack)

您可以将其与一维数组A[x]进行比较:

Ldloc A //(load array A onto the operation stack)
Ldloc x //(load value of variable x onto the operation stack)
Ldelem_I4 //(return the 4-byte signed integer from the array at index [x] and put the result onto the operation stack)

答案 2 :(得分:-1)

  

但是,您如何描述结构多态性,即数组可以有多个维度的事实?

三点:

  • 在语言层面,多维数组将符合内部多态性
  • 由于多维数组可以使用关联数组或列表进行模拟,因此不需要依赖于特定的数据结构
  • 由于可以在运行时创建多维数组,因此不需要依赖于类型检查

<强>参考