2017-03-25 5 views
4

den folgenden Code Gegeben:Wie unterscheidet man die Typen: Int32 [] & Int32 [*]?

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

ein Array-Typ (ein Typ, wo .IsArray true zurück) Da, wie kann ich zwischen diesen beiden Arten von Array-Typen zuverlässig differenciate?

Ohne hacky Lösungen vorzugsweise zu verwenden (wie instanziieren des Typs oder Suchen nach "*" im Namen).

Kontext: Ich baue einen Serialisierer und ich brauche das für jeden Typ, den es gibt, also konstante Vergleiche wie == typeof (int []) wird nicht funktionieren.

+1

'type.IsArray!? "Nicht Array": type.GetArrayRank()> 1? "Mehrdimensionales Array": type == type.GetElementType(). MakeArrayType()? "Nullbasiertes Array": "Nicht nullbasiertes Array" – PetSerAl

+0

Eine Frage wie diese benötigt ein wenig mehr Kontext, ich würde niemals einen Stringvergleich auf den Typnamen empfehlen, aber die offensichtliche Antwort auf Ihre Frage ist type2! = typeof (int []). Wenn wir mehr Kontext darüber haben, woher diese Typen oder Variablen stammen (nur ein paar einfache Informationen), können wir Ihnen möglicherweise einige wirklich nützliche Antworten geben. –

+0

@PetSerAl Das ist eine brillante Antwort! Vielen Dank, ich werde es gleich ausprobieren. & Chris Schaller Ich baue einen Serialisierer und ich brauche es für jeden Typ, so dass eine ständige Überprüfung auf typeof (int []) nicht funktioniert, ich füge das zu meiner Frage hinzu. – hl3mukkel

Antwort

1

Wenn der Werttyp ist bekannt:

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

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


Weitere Unterschiede, die ein bisschen nützlich sein könnten:

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

Schön entdeckt! Das könnte sich jedoch in zukünftigen Versionen der CLR ändern, also werde ich PetSeAl's Lösung gehen, danke aber! – hl3mukkel

2

prüfen, ob der Typ einen Vergleich fehlschlägt ist eine gültige Option, wenn Sie jedoch bestimmte Eigenschaften eines Typs überprüfen möchten Um beispielsweise zu wissen, um welchen Array-Typ es sich handelt, können Sie mit Type.GetElementType() prüfen und bestätigen, dass die Elemente im Array vom selben Typ sind. Der folgende Code könnte Ihre investagations helfen:

// 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-Konsole Ausgabe:

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