2011-12-09 5 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; 
     } 
    } 
} 
  • は型をチェックするマージされた解決策はありますか?ご覧のとおり、FooのクラスとFooから派生したクラスのクラスを取得するには、IsSubClassOf + FullNameを使用しています。

  • c、f、kを除くすべてのチェック(a〜j)は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]]

    propTypeがタイプDbSet<>であるかどうかを確認するために他の方法はありますか?
    ありがとうございます。

+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<>のサブクラスに対処する必要がありますか?ない場合は、使用することができます。

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などは動作しません。以下の条件が真の場合TypexはタイプDbSet<T>は次のとおりです。

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

を返します。しかし、私は 'GetGenericTypeBase()'インスタンスメソッドを見つけることができませんでした。あなたは 'GetGenericTypeDefinition()'を意味しましたか? – Kamyar

+0

@Kamyar申し訳ありませんが、私は 'GetGenericTypeDefinition'(固定)を意味しました。 – dasblinkenlight

+0

答えをありがとう。 – Kamyar

関連する問題