2017-08-15 111 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

相關問題