2017-03-25 10 views
4

次のコードを考える:配列型(.IsArrayがtrueを返す型)を考えるタイプを区別する方法:Int32 []&Int32 [*]?

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

を、どのように確実に配列型のもの二種類が区別さができますか?

好ましくは、ハッキングされたソリューションを使用しないでください(タイプのインスタンス化や名前の「*」の検索など)。

コンテキスト:私はシリアライザを構築していますが、これはすべてのタイプに対応するために必要です。したがって、== typeof(int [])のような定数比較は機能しません。

+1

'type.IsArrayを!? "配列ではない":type.GetArrayRank()> 1? "多次元配列":type == type.GetElementType()。MakeArrayType()? "ゼロベースの配列": "非ゼロベースの配列" – PetSerAl

+0

このような質問にはもう少しコンテキストが必要ですが、型名に文字列比較を使用することは勧めませんが、質問に対する明白な答えはtype2です! = 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

はチェックを有効なオプションですが、typの特定のプロパティを調べたい場合たとえば、どの型の配列をキャストするかを知るためには、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 
関連する問題