Search code examples
c#reflectioncomparison

C# Type comparison using reflection


I'd like to check if a property is of type DbSet<T> using reflection.

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

By using reflection:

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;
        }
    }
}
  • Is there a merged solution to check the type? As you can see, I'm using IsSubClassOf + FullName to get classes of type Foo and any other class which is derived from Foo.

  • all the checks (a to j) except c,f,k return false. c,f return System.Object as BaseType which is no use for me. k, I consider an unsafe check. But will be my what I use if no other workaround is found. In debug mode, the propType's FullName is:

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

    Is there any other way to check if propType is of type DbSet<>?
    Thanks.


Solution

  • Do you need it to cope with subclasses of DbSet<> as well? If not, you can use:

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

    Full sample:

    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);
            }
        }
    }
    

    With subclasses you'd just need to apply the same test recursively up the inheritance hierarchy. It becomes more of a pain if you need to test for interfaces.