2011-12-09 77 views
2

我想檢查一個屬性是否使用反射類型DbSet<T>C#使用反射的類型比較

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

通過使用反射:

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; 
     } 
    } 
} 
  • 是否有合併的解決方案來檢查類型?正如您所看到的,我使用IsSubClassOf + FullName來獲得類型Foo的類和從Foo派生的任何其他類。

  • 所有檢查(a到j)除c,f,k都返回false。 c,f返回System.Object作爲BaseType,這對我沒有用處。 k,我認爲不安全檢查。但如果沒有找到其他解決方法,我將會使用它。在調試模式下,propTypeFullName是:

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

    是否有任何其他的方法來檢查,如果propTypeDbSet<>類型的?
    謝謝。

+0

你可以使用PropertyInfo.PropertyType這裏是一個鏈接到該MS 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<>以及子?如果沒有,你可以使用:

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<>)表示常規類型。它不是一個正常的類型:相反,它是一個泛型類型定義。這就是爲什麼IsAssignableFromIsSubclassOf等不起作用。 TypexDbSet<T>型的,如果以下條件爲真:

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

謝謝。但我找不到任何'GetGenericTypeBase()'實例方法。你的意思是'GetGenericTypeDefinition()'? – Kamyar

+0

@Kamyar對不起,我的意思是'GetGenericTypeDefinition'(固定)。 – dasblinkenlight

+0

感謝您的回答。 – Kamyar