2017-03-25 41 views
4

鑑於以下代碼:如何區分類型:Int32 []和Int32 [*]?

var type1 = typeof(int[]); // Int32[] 
var type2 = Array.CreateInstance(elementType: typeof(int), 
           lengths: new [] {0}, 
           lowerBounds: new []{1}).GetType(); // Int32[*] 

鑑於數組類型(A型,其中.IsArray返回true),我怎樣才能可靠地那些2種陣列類型之間differenciate?

在不使用任何哈克溶液優選(如實例化的類型或尋找「*」的名稱)。

語境:我建立一個串行器與我需要這對每個類型有,像== typeof運算(INT [])將無法工作,所以不斷的比較工作。

+1

'type.IsArray!? 「Not array」:type.GetArrayRank()> 1? 「Multidimensional array」:type == type.GetElementType()。MakeArrayType()? 「零基陣」:「不從零開始的數組」' – PetSerAl

+0

一個問題,這樣需要多一點點背景下,我絕不會建議使用的類型名稱的字符串對比,但答案很明顯,你的問題是2型! = typeof(int [])。如果我們對這些類型或變量從(只是一些簡單的信息)採購更多的上下文那麼我們也許能夠給你一些真正有用的答案 –

+0

@PetSerAl這是一個輝煌的答案!非常感謝你嘗試一下。 &Chris Schaller我正在構建一個序列化器,並且我需要它來處理每種類型,所以對typeof(int [])進行常量檢查將不起作用,我會將其添加到我的問題中。 – hl3mukkel

回答

1

如果值類型是已知的:

var t1 = type1 == typeof(int[]); // true 
var t2 = type2 == typeof(int[]); // false 

參考How to check if object is an array of a certain type?


其它差異,可能是一個比特有用:如果類型失敗的比較

var tt1 = type1.GetConstructors().Length; // 1 
var tt2 = type2.GetConstructors().Length; // 2 

var ttt1 = type1.GetMembers().Length; // 47 
var ttt2 = type2.GetMembers().Length; // 48 
+0

很好的發現!然而,這可能會改變未來版本的CLR,所以我會去PetSerAl的解決方案,謝謝! – hl3mukkel

2

檢查是一個有效的選項,但是如果你想檢查一個典型的特定屬性例如,要知道要將其轉換爲什麼類型的數組,可以使用Type.GetElementType()來檢查並確認數組中的元素是相同類型的。下面的代碼可能會幫助您investagations:

// Initialise our variables 
object list1 = new int[5]; // Int32[] 
object list2 = Array.CreateInstance(elementType: typeof(int), 
            lengths: new[] { 0 }, 
            lowerBounds: new[] { 1 }); 
var type1 = list1.GetType(); 
var type2 = list2.GetType(); 

Debug.WriteLine("type1: " + type1.FullName); 
Debug.WriteLine($"type1: IsArray={type1.IsArray}; ElementType={type1.GetElementType().FullName}; Is Int32[]: {type1 == typeof(Int32[])}"); 
Debug.WriteLine("type2: " + type2.FullName); 
Debug.WriteLine($"type2: IsArray={type2.IsArray}; ElementType={type2.GetElementType().FullName}; Is Int32[]: {type2 == typeof(Int32[])}"); 

// To make this useful, lets join the elements from the two lists 
List<Int32> outputList = new List<int>(); 
outputList.AddRange(list1 as int[]); 
if (type2.IsArray && type2.GetElementType() == typeof(Int32)) 
{ 
    // list2 can be safely be cast to an Array because type2.IsArray == true 
    Array arrayTemp = list2 as Array; 
    // arrayTemp can be cast to IEnumerable<Int32> because type2.GetElementType() is Int32. 
    // We have also skipped a step and cast ToArray 
    Int32[] typedList = arrayTemp.Cast<Int32>().ToArray(); 
    outputList.AddRange(typedList); 
} 

// TODO: do something with these elements in the output list :) 

調試控制檯輸出:

type1: System.Int32[] 
type1: IsArray=True; ElementType=System.Int32; Is Int32[]: True 
type2: System.Int32[*] 
type2: IsArray=True; ElementType=System.Int32; Is Int32[]: False 
相關問題