2009-10-30 5 views
11

나는 Type 개체의 특정 인스턴스가 일반적인 "는 IEnumerable"인 경우 감지하기 위해 노력하고있어 ....NET 반사 : 검출는 IEnumerable <T>

내가 가지고 올 수있는 최선은 다음과 같습니다

// theType might be typeof(IEnumerable<string>) for example... or it might not 
bool isGenericEnumerable = theType.GetGenericTypeDefinition() == typeof(IEnumerable<object>).GetGenericTypeDefinition() 
if(isGenericEnumerable) 
{ 
    Type enumType = theType.GetGenericArguments()[0]; 
    etc. ...// enumType is now typeof(string) 

하지만 약간 간접적 인 것처럼 보입니다. 직접 /보다 우아한 방법이 있습니까?

+0

내 후속 조치를 참조하십시오. http://stackoverflow.com/questions/1650310/net-reflection-determining-whether-an-array-of-t-would-be-convertible-to-some-o –

답변

22

당신은

if(theType.IsGenericType && theType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) 
{ 
    Type underlyingType = theType.GetGenericArguments()[0]; 
    //do something here 
} 

편집을 사용할 수 있습니다 다음 IsGenericType 검사를 추가, 유용한 의견을 주셔서 감사합니다 당신은 따라서 비 일반 종류에 GetGenericTypeDefinition()를 호출 할 수 없습니다

+2

꽤 나쁜 엉덩이, 바로 거기. –

+2

theType이 generic이 아니면'InvalidOperationException'을 던져 버릴 것입니다 - IMHO를 확인하는 좋은 해결책은 아닙니다. – Lucero

+3

이것은 'theType'이 정확히 typeof (IEnumerable <>)이고 형식이 인터페이스를 구현하는 경우가 아닌 경우에만 작동합니다. 다행히 그게 네가 한 일이야. –

2

주, IsGenericType와 먼저 확인.

유형이 일반 IEnumerable<>을 구현하는지 여부를 확인하려는 경우 또는 인터페이스 유형이 IEnumerable<>인지 확인하려는 경우 확실하지 않습니다.

if (typeof(IEnumerable).IsAssignableFrom(type)) { 
    foreach (Type interfaceType in type.GetInterfaces()) { 
     if (interfaceType.IsGenericType && (interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))) { 
      Console.WriteLine("{0} implements {1} enumerator", type.FullName, interfaceType.FullName); // is a match 
     } 
    } 
} 
+0

은 레거시 (비 제너릭) IEnumerable 인터페이스를 나타내는이 코드입니까? –

+0

내 질문을 명확히하겠습니다 ... –

+0

예를 들어, 일반적인 하나의 비 제네릭 하나를 의미하기 때문에, 그것은 인터페이스를 통해 갈 가치가 있는지 확인하는 빠른 검사입니다. 'IEnumerable' (non-generic)이 구현되어 있지 않다면,'IEnumerable <>'(generic)은 될 수 없습니다. – Lucero

4

특정 타입이 IEnumerable<T> 인터페이스를 구현하는 경우를 결정하는 코드의 부분을 사용할 수있다 : 첫 번째 경우에있어서, 다음 코드 (interfaceType와 내부 검사가 두 번째의 경우이다)을 사용. 그러나 그것은 하지 작업 유형은 당신이 통과 할 경우

Type type = typeof(ICollection<string>); 

bool isEnumerable = type.GetInterfaces()  // Get all interfaces. 
    .Where(i => i.IsGenericType)    // Filter to only generic. 
    .Select(i => i.GetGenericTypeDefinition()) // Get their generic def. 
    .Where(i => i == typeof(IEnumerable<>)) // Get those which match. 
    .Count() > 0; 

그것은 어떤 인터페이스의 작동은 IEnumerable<T>입니다.

각 인터페이스에 전달 된 형식 인수를 확인하기 위해이를 수정할 수 있어야합니다.

+0

Where(). Count() 대신 Any()를 사용할 수 있습니다. – Fred