2017-03-25 3 views
4

다음 코드를 감안할 때 :형식을 구분하는 방법 : Int32 [] & Int32 [*]?

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

배열 형 (.IsArray 사실 반환하는 유형), 어떻게 안정적으로 배열 형의 그 이가지 사이 differenciate 수 있습니다 감안할 때?

해킹 된 솔루션을 사용하지 않는 것이 좋습니다 (유형을 인스턴스화하거나 이름에서 "*"를 찾는 것과 같습니다).

컨텍스트 : serializer를 구축 중이며 모든 유형에 대해 작동해야하므로 == typeof (int [])와 같은 상수 비교가 작동하지 않습니다.

+1

'type.IsArray을!? "배열이 아닙니다": type.GetArrayRank()> 1? "다차원 배열": type == type.GetElementType(). MakeArrayType()? "0에 기반을 둔 배열": "0이 아닌 배열" – PetSerAl

+0

이 질문에는 조금 더 많은 문맥이 필요합니다. 유형 이름에 문자열 비교를 사용하는 것은 권장하지 않지만 질문에 대한 확실한 답은 type2입니다! = typeof (int []). 이러한 유형이나 변수가 어디에서 왔는지에 대한 컨텍스트가 있다면 (몇 가지 간단한 정보) 우리는 여러분에게 정말 유용한 대답을 줄 수 있습니다. –

+0

@PetSerAl 그것은 훌륭한 대답입니다! 너무 많이 시도해 주셔서 감사합니다. & Chris Schaller serializer를 만들고 있는데 모든 유형에서 작동해야하므로 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