2017-08-15 80 views
13

很简单:数组类型具有相同的元素类型和级别不等于

var equal1 = typeof(object[]) == typeof(object).MakeArrayType(); 
var equal2 = typeof(object[]) == typeof(object).MakeArrayType(1); 
var equal3 = typeof(object[,]) == typeof(object).MakeArrayType(2); 

的假设是,所有这三个应该是真实的,但事实证明,equal2false - 这并没有真正意义给予前两个MakeArrayType调用是等价的,结果数组类型是相同的。

我实际上可以辨别的唯一的区别是明确地传递数组类型的秩为“1”产生一个TypeName"Object[*]"而省略它产生"Object[]"

所以我想,也许object[]秩不1(即使它显然是!) - 所以我这样做:现在

var type1 = typeof(object[]); 
var type2 = type1.GetElementType().MakeArrayType(type1.GetArrayRank()); 
var equal = type1 == type2; //false 

类型肯定有相同的排名,但不平等。

这种情况更像是我目前的情况下,我尝试建立阵列协方差为Rezolver - 所以我步行的基础层次结构和使用MakeArrayType与原数组类型的排名重新构图数组类型。

所以 - 任何人都可以解释为什么两个相同排名的数组类型不被认为是相等的吗?

我意识到这里可能存在一些细微差别,并且有可以使用的解决方法,我只是好奇到底发生了什么事情!

回答

20

documentation解释的区别:

公共语言运行时使得矢量之间的区别(即,一维数组,它们总是从零开始)和多维数组。一个向量总是只有一个维度,它不同于恰好只有一个维度的多维数组。您不能使用此方法重载来创建矢量类型;如果rank为1,则此方法重载将返回恰好具有一个维度的多维数组类型。使用MakeArrayType()方法重载来创建矢量类型。

因此,基本上,equal1返回一个矢量,并且equal2返回一个多维数组碰巧具有这两种类型的CLR处理非常不同的1

秩。

有趣的是,如果创建的类型的实例,则结束了一个矢量再次:

var type = typeof(object).MakeArrayType(1); 
// Create an instance with length 2 
var array = Activator.CreateInstance(type, 2); 
Console.WriteLine(array.GetType());   // System.Object[] 
Console.WriteLine(type);      // System.Object[*] 

Array.CreateInstance示出相同的行为:如果你要求的阵列具有下界0和1级,它总是会创建矢量:

var array = Array.CreateInstance(typeof(object), new[] { 2 }, new[] { 0 }); 
Console.WriteLine(array.GetType()); 
object[] objArray = (object[]) array; // This is fine 

如果你改变了0到任何非零值,它会创建一个System.Object[*]和演员将失败。

+0

我想象一个以矢量结尾的是编译器部分的优化,因为'2'在这种情况下将代表数组的大小[又名矢量]。 – JuanR

+1

@Juan:实例创建与编译器无关 - 它是运行时/框架。 Activator.CreateInstance(type)'创建一个* * *类型的实例是很奇怪的。 –

+1

谢谢@JonSkeet。我错过了。我的意思是说运行时可能会优化操作。激活器也有可能具有内部逻辑,这决定了你正在请求相当于一个向量。当我有机会时,我会尽力找到消息来源,并看一看。重点是,正在确定结果等同于一个向量。 – JuanR

相关问题