2009-12-04 2 views
48

개체의 형식이 IEnumerable인지 확인하는 방법 <T>?컬렉션의 형식이 IEnumerable인지 확인 <T>

코드 :

namespace NS { 
    class Program { 
     static IEnumerable<int> GetInts() { 
      yield return 1; 
     } 
     static void Main() { 
      var i = GetInts(); 
      var type = i.GetType(); 
      Console.WriteLine(type.ToString()); 
     } 
    } 
} 

출력 :

NS.1.Program+<GetInts>d__0 

내가 IList의를 반환하는 GetInts을 변경하면 모든 것이 OK입니다 출력은 다음과 같습니다

System.Collections.Generic.List`1[System.Int32] 

그리고이 false를 반환 :

당신이 그 그러나

var asEnumerable = i as IEnumerable<int>; 
if(asEnumerable != null) { ... } 

, 내가 (이 예에서) 가정 있어요 Type :

namespace NS { 
    class Program { 
     static IEnumerable<int> GetInts() { 
      yield return 1; 
     } 
     static void Main() { 
      var i = GetInts(); 
      var type = i.GetType(); 
      Console.WriteLine(type.Equals(typeof(IEnumerable<int>))); 
     } 
    } 
} 

답변

98

당신은 수집, 그럼 그냥 as을 의미하는 경우

객체 것 ""유형이 될 수는 없지만 을 구현할 수 있습니다. 나는 그것을 기대할 것이다 :

if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...} 

할 것이다.

static Type GetEnumerableType(Type type) { 
    foreach (Type intType in type.GetInterfaces()) { 
     if (intType.IsGenericType 
      && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { 
      return intType.GetGenericArguments()[0]; 
     } 
    } 
    return null; 
} 

및 전화 : 당신이 T (위의 int)를 알 수없는 경우, 모든 구현 된 인터페이스를 확인

Type t = GetEnumerableType(type); 

을이 null의 경우, 그것은을위한 IEnumerable<T>하지 않습니다 모든 T - 그렇지 않으면 t을 확인하십시오.

+17

을 'System.String'은'IEnumerable '을 구현한다는 것을 기억하십시오. – mayu

+1

@Tymek 참으로 - 원시 타입, 내장 타입 및 콜렉션을 다루는 라이브러리 작업을 많이하고 있습니다. 그리고 그 이유 때문에 일반화를 적용하기 전에'string' * 같은 시나리오를 추출하는 것이 사실상 항상 필요합니다. –

+4

형식이 ICollection 이고 IEnumerable 을 구현하는 경우 if 문은 true로 평가되지 않습니다. IEnumerable 또는 하위 클래스 중 하나임을 알 수있는 방법이 있습니까? –

3

iIEnumerable<int>의 아류 형이다NS.1.Program+<GetInts>d__0,이다. 따라서

if (i is IEnumerable<int>) { ... } 

또는 IsAssignableFrom (Marc의 대답과 유사) 중 하나를 사용할 수 있습니다.

1

is 키워드를 사용할 수 있습니다.

[TestFixture] 
class Program 
{ 
    static IEnumerable<int> GetInts() 
    { 
     yield return 1; 
    } 

    [Test] 
    static void Maasd() 
    { 
     var i = GetInts(); 
     Assert.IsTrue(i is IEnumerable<int>); 
    } 
} 
13

같은 마크의 답변으로 기술하지만, Linqier : 객체가 <T>는 IEnumerable 유형 의 경우

namespace NS 
{ 
    class Program 
    { 
     static IEnumerable<int> GetInts() 
     { 
      yield return 1; 
     } 

     static void Main() 
     { 
      var i = GetInts(); 
      var type = i.GetType(); 
      var isEnumerableOfT = type.GetInterfaces() 
       .Any(ti => ti.IsGenericType 
        && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)); 
      Console.WriteLine(isEnumerableOfT); 
     } 
    } 
} 
7

을 확인하는 방법?

개체가 IEnumerable 인터페이스를 구현하는지 확인하려면이 훌륭한 초소형 일반 확장 메서드를 자유롭게 사용하십시오. 오브젝트 유형을 확장하므로 사용중인 모든 오브젝트의 인스턴스를 사용하여 실행할 수 있습니다.

public static class CollectionTestClass 
{ 
    public static Boolean IsEnumerable<T>(this Object testedObject) 
    { 
     return (testedObject is IEnumerable<T>); 
    } 
} 
13

이후 IEnumerable을 <T> 상속을 IEnumerable (비 제네릭)과 유형 <T>는 IEnumerable 단지는 IEnumerable과하지 않을 때 당신이 알 필요가없는 경우 다음 사용할 수 있습니다

if (typeof(IEnumerable).IsAssignableFrom(srcType))