2017-03-25 42 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 
相关问题