2011-12-09 3 views
2

속성이 DbSet<T> 리플렉션을 사용하는지 확인하고 싶습니다.C# 리플렉션을 사용하여 유형 비교

var types = Assembly.GetExecutingAssembly().GetTypes(); 
foreach (var type in types) 
{ 
    if (type.IsSubclassOf(typeof (Foo)) || type.FullName == typeof (Foo).FullName) 
    { 
     foreach (
      var prop in Type.GetType(type.FullName). 
       GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)) 
     { 
      var propType = prop.PropertyType; 
      bool a = propType.IsAssignableFrom(typeof (DbSet<>)); 
      bool b = typeof (DbSet<>).IsAssignableFrom(propType); 

      bool c = propType.BaseType.IsAssignableFrom(typeof (DbSet<>)); 
      bool d = typeof (DbSet<>).IsAssignableFrom(propType.BaseType); 


      bool e = typeof (DbSet<>).IsSubclassOf(propType); 
      bool f = typeof (DbSet<>).IsSubclassOf(propType.BaseType); 
      bool g = propType.IsSubclassOf(typeof (DbSet<>)); 
      bool h = propType.BaseType.IsSubclassOf(typeof (DbSet<>)); 

      bool i = propType.BaseType.Equals(typeof (DbSet<>)); 
      bool j = typeof (DbSet<>).Equals(propType.BaseType); 

      bool k = propType.Name == typeof (DbSet<>).Name; 
     } 
    } 
} 
  • 유형을 확인하는 통합 된 솔루션이 있습니까 : 사용하는 반사에 의해

    public class Foo 
    { 
        public DbSet<Bar> Bars { get; set; } 
    } 
    

    ? 보시다시피 Foo 클래스와 Foo에서 파생 된 클래스를 가져 오려면 IsSubClassOf + FullName을 사용하고 있습니다.

  • c, f, k를 제외한 모든 검사 (a ~ j)는 false를 반환합니다. c, f System.Object를 BaseType으로 반환합니다.이 형식은 저에게 유용하지 않습니다. k, 나는 안전하지 않은 검사을 고려합니다. 그러나 다른 대안이 발견되지 않으면 내가 사용하는 것입니다. 디버그 모드에서 propTypeFullName은 다음과 같습니다 propType 유형 DbSet<> 인 경우 확인하는 다른 방법은

    System.Data.Entity.DbSet`1[[Console1.Bar, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

    있습니까?
    감사합니다.

+0

PropertyInfo.PropertyType을 사용할 수 있습니까? http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.propertytype.aspx – MethodMan

+0

@DJKRAZE :'PropertyInfo. PropertyType'은'System.Data.Entity.DbSet'1 [[Console1.Bar, ...]' – Kamyar

답변

5

당신은뿐만 아니라 DbSet<>의 서브 클래스에 대처하는 것이 필요하십니까 : 다음 조건에 해당하는 경우 Typex 유형 DbSet<T>이다? 그렇지 않다면, 당신은 사용할 수 있습니다

if (propType.IsGenericType && 
    propType.GetGenericTypeDefinition() == typeof(DbSet<>)) 

전체 샘플 : 서브 클래스로

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 

class Test<T> 
{ 
    public List<int> ListInt32 { get; set; } 
    public List<T> ListT { get; set; } 
    public string Other { get; set; } 
    public Action<string> OtherGeneric { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var query = from prop in typeof(Test<string>).GetProperties() 
        let propType = prop.PropertyType 
        where propType.IsGenericType && 
          propType.GetGenericTypeDefinition() == typeof(List<>) 
        select prop.Name; 

     foreach (string name in query) 
     { 
      Console.WriteLine(name); 
     } 
    } 
} 

방금 ​​상속 계층까지 반복적으로 동일한 테스트를 적용해야 할 것입니다. 인터페이스를 테스트해야하는 경우 더 많은 고통을 느끼게됩니다.

+0

감사합니다. 'GetGenericTypeDefinition'이 트릭을했습니다. – Kamyar

2

코드의 문제점은 typeof(DbType<>)이 일반 유형임을 나타냅니다. 이것은 일반적인 유형이 아니라 오히려 일반적인 유형 정의입니다. 그래서 IsAssignableFrom, IsSubclassOf 등은 작동하지 않습니다.

x.IsGenericType && x.GetGenericTypeDefinition() == typeof(DbSet<>) && x.GetGenericTypeArguments()[0] == typeof(T) 
+0

감사합니다. 그러나'GetGenericTypeBase()'인스턴스 메소드를 찾을 수 없었습니다. 'GetGenericTypeDefinition()'을 의미 했습니까? – Kamyar

+0

@Kamyar 죄송합니다,'GetGenericTypeDefinition' (고정)을 의미했습니다. – dasblinkenlight

+0

답해 주셔서 감사합니다. – Kamyar

관련 문제