C#使用反射进行类型比较

Kam*_*yar 2 c# reflection comparison

我想检查属性是否是DbSet<T>使用反射的类型.

public class Foo
{
    public DbSet<Bar> Bars { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

通过使用反射:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 是否有合并的解决方案来检查类型?正如您所看到的,我正在使用IsSubClassOf+ FullName来获取类型的类Foo以及派生自的任何其他类Foo.

  • 除了c,f,k之外的所有检查(a到j)都返回false.c,f将System.Object作为BaseType返回,对我来说没用.k,我认为是不安全的检查.但如果找不到其他解决方法,那将是我使用的.在调试模式中,propType's FullName是:

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

    有没有其他方法来检查是否propType类型DbSet<>
    谢谢.

Jon*_*eet 5

你需要它来处理子类DbSet<>吗?如果没有,您可以使用:

if (propType.IsGenericType &&
    propType.GetGenericTypeDefinition() == typeof(DbSet<>))
Run Code Online (Sandbox Code Playgroud)

完整样本:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

对于子类,您只需要在继承层次结构中递归地应用相同的测试.如果您需要测试接口,那将变得更加痛苦.