2009-07-13 2 views
51

유형 MyType이 있다고 가정 해 봅시다. 나는 다음을 수행 할 :에 대한 답변 (1) 예, T가 무엇인지 찾을 경우합니다 MyType 일부 T. 유형이 일반 인터페이스를 구현하는지 알아 내기

  • 를 들어,은 IList 인터페이스를 구현하는 경우

    1. 가 알아보십시오.

    이렇게하는 방법은 GetInterface()이지만 특정 이름으로 만 검색 할 수 있습니다. "양식은 IList의 모든 인터페이스"를 검색 할 수있는 방법이 있나요

    관련 (인터페이스가 IList의의 서브 인터페이스 인 경우는 일 경우는 유용 할 woudl 가능한 경우.) : How to determine if a type implements a specific generic interface type

  • 답변

    80
    // this conditional is necessary if myType can be an interface, 
    // because an interface doesn't implement itself: for example, 
    // typeof (IList<int>).GetInterfaces() does not contain IList<int>! 
    if (myType.IsInterface && myType.IsGenericType && 
        myType.GetGenericTypeDefinition() == typeof (IList<>)) 
        return myType.GetGenericArguments()[0] ; 
    
    foreach (var i in myType.GetInterfaces()) 
        if (i.IsGenericType && i.GetGenericTypeDefinition() == typeof (IList<>)) 
         return i.GetGenericArguments()[0] ; 
    

    편집 : myTypeIDerivedFromList<>하지만 직접 IList<>, IList<> 의지를 구현하더라도 GetInterfaces()에 의해 반환 된 배열에 나타납니다.

    업데이트 :myType이 문제의 일반적인 인터페이스 인 경우를 확인했습니다.

    +0

    배열의 대소 문자도 처리합니다. 명시 적으로 배열을 테스트하려면 "if (myType.IsArray) return myType.GetElementType();"을 사용하십시오. (그리고 이것이 더 빠를 수도 있지만 성능에있어서 중요한 것은 아무도 없길 바랍니다.) – yoyo

    +0

    .IsInterface가 필요한 이유에 대해 궁금한 저와 같은 분을 위해 : GetGenericTypeDefinition()은 제네릭이 아닌 유형에서 호출 된 경우 throw됩니다. – GameFreak

    +0

    Type.IsGenericType 속성은 netstandard 1.6 이하에서는 사용할 수 없으므로 .NET Core 1.0에서는 사용할 수 없지만 type.GetTypeInfo(). IsGenericType 대신 TypeInfo.IsGenericType을 사용할 수 있습니다. – dotarj

    0

    하는 경우 나는 당신의 질문을 정확하게 이해합니다. 당신이하려고하는 것입니다. 그렇지 않은 경우 더 자세히 설명하십시오.

    public class MyType : ISomeInterface 
    { 
    } 
    
    MyType o = new MyType(); 
    
    if(o is ISomeInterface) 
    { 
    } 
    

    편집 : 당신이 당신의 질문을 변경 경우, 당신이 속하지 않는처럼 내 대답은 보이는 지금 edited..because 사실을 추가하십시오. 이 경우

    , 여기에 매우 큰 LINQ

      var item = typeof(MyType).GetInterfaces() 
              .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>)) 
              .Select(t => t.GetGenericArguments().First()) 
              .FirstOrDefault(); 
    
    if(item != null) 
    //it has a type 
    
    11

    당신은 이렇게 쉽게 할 수 반사를 사용 (일부 LINQ) :

    public static IEnumerable<Type> GetIListTypeParameters(Type type) 
    { 
        // Query. 
        return 
         from interfaceType in type.GetInterfaces() 
         where interfaceType.IsGenericType 
         let baseInterface = interfaceType.GetGenericTypeDefinition() 
         where baseInterface == typeof(IList<>) 
         select interfaceType.GetGenericArguments().First(); 
    } 
    

    먼저 유형에 인터페이스를 받고에만 제네릭 형식을있는 그 사람들을 위해 필터링된다.

    그런 다음 해당 인터페이스 유형에 대한 제네릭 형식 정의를 가져와 IList<>과 같은지 확인하십시오.

    거기에서 원래 인터페이스에 대한 일반적인 인수를 얻는 것이 간단합니다.

    형식에 IList<T> 개의 구현이 여러 개있을 수 있으므로 IEnumerable<Type>이 반환됩니다.도우미 메서드 확장으로

    +0

    반환 식을 괄호로 묶고 끝에 ".First()"를 추가하면 Length-1 IEnumerable 대신 Type이 반환됩니다. 다루기가 쉽습니다. (개인적으로 이것은 LINQ와는 너무 똑똑한 예라고 생각하지만, 아마도 저만 그렇습니다.) – yoyo

    +0

    @yoyo 또는이 메서드의 결과에 'First'를 호출하면됩니다. 이 메서드에서'First'를 반환하면 * 틀린 * 하나의 형식 매개 변수를 가정합니다. – casperOne

    +0

    좋은 점 @casperOne, OP의 MyType은 IList 및 IList 을 구현할 수 있습니다. 따라서 질문은 "T를 찾아야"하는 것이어야합니다. "T를 찾으십시오". 허용 된 대답은이 문제를 다루지 않습니다. – yoyo

    1

    public static bool Implements<I>(this Type type, I @interface) where I : class 
    { 
        if(((@interface as Type)==null) || !(@interface as Type).IsInterface) 
         throw new ArgumentException("Only interfaces can be 'implemented'."); 
    
        return (@interface as Type).IsAssignableFrom(type); 
    } 
    

    사용 예 : 안톤 Tykhyy의 제안을 사용

    var testObject = new Dictionary<int, object>(); 
    result = testObject.GetType().Implements(typeof(IDictionary<int, object>)); // true! 
    
    4
    public static bool Implements<I>(this Type type) where I : class 
        { 
         if (!typeof(I).IsInterface) 
         { 
          throw new ArgumentException("Only interfaces can be 'implemented'."); 
         } 
    
         return typeof(I).IsAssignableFrom(type); 
        } 
    
    1

    는, 여기에 몇 가지 유형으로 일반적인 인터페이스를 구현하는 경우 확인하는 작은 확장 메서드입니다 하나의 제네릭 유형 매개 변수가 제공됩니다.

    public static class ExtensionMethods 
    { 
        /// <summary> 
        /// Checks if a type has a generic interface. 
        /// For example 
        ///  mytype.HasGenericInterface(typeof(IList<>), typeof(int)) 
        /// will return TRUE if mytype implements IList<int> 
        /// </summary> 
        public static bool HasGenericInterface(this Type type, Type interf, Type typeparameter) 
        { 
         foreach (Type i in type.GetInterfaces()) 
          if (i.IsGenericType && i.GetGenericTypeDefinition() == interf) 
           if (i.GetGenericArguments()[0] == typeparameter) 
            return true; 
    
         return false; 
        } 
    } 
    
    관련 문제