简体   繁体   中英

How to differentiate the types: Int32[] & Int32[*]?

Given the following code:

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

Given an array type (a Type where .IsArray returns true), how can I reliably differenciate between those two kinds of array types?

Without using any hacky solutions preferably (like instantiating the type or looking for "*" in the name).

Context: I am building a serializer and I need this to work for every Type there is, so constant comparisons like == typeof(int[]) won't work.

Checking if the type fails a comparison is a valid option, however if you want to inspect specific properties of a type, for instance to know what type of array to cast it to, you can use the Type.GetElementType() to inspect and confirm that the elements in the array are of the same type. The following code might help your 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 :)

Debug console output:

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

If the value type is known:

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

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


Other differences that might be a bit useful:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM