1

See this code

    public class Person
    {
        public int Id { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public Dictionary<long,float> No {get;set;}
        public DateTime BirthDate { get; set; }
    }

    public class Manager
    {
        public int Id { get; set; }
        public User User { get; set; }
        public List<User> Users { get; set; }
    }

    public class User
    {
        public int Id { get; set; }
        public Person Person { get; set; }
        public List<string> Phones { get; set; }

    }

How to find all types that used in specific type properties recursively ? for example

GetAllInternalTypes(typeof(Manager))

Result for Manager: (Manager => User => Person)

  • int
  • User
  • List< User >
  • Person
  • List< string >
  • string
  • DateTime
  • Dictionary< long,float >
  • long
  • float

I want to find all used Types of an specific type recursively.

HamedFathi
  • 3,667
  • 5
  • 32
  • 72

1 Answers1

1

Your question is little bit tricky. because you want to only get properties of your types not built in types of .Net libraries. for example Dictionary, String, DateTime, Array etc, have their own properties that you want to exclude. fortunately there are ways to know if type is your defined type or is from System library.

How to determine if a object type is a built in system type

Also I preferred to return PropertyInfo instead of Type because it gives more information, if you want to only get Type of properties you can easily do that using linq.

var types = properties.OrderBy(p => p.DeclaringType).Select(p => p.PropertyType).Distinct().ToList();

Here is the algorithm with simple test

static void Main(string[] args)
{
    var properties = GetTypes(typeof(Manager));

    foreach (var propertyInfo in properties)
    {
        Console.WriteLine("{0,-20}{1,-20}{2}", 
            propertyInfo.PropertyType.Name, 
            propertyInfo.DeclaringType?.Name,
            propertyInfo.Name);
    }
}

public static List<PropertyInfo> GetTypes(Type type)
{
    if (type.Module.ScopeName == "CommonLanguageRuntimeLibrary" || // prevent getting properties of built-in type
    type == type.DeclaringType)                                    // prevent stack overflow
    {
        return new List<PropertyInfo>();
    }

    const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

    List<PropertyInfo> result = type
        .GetProperties(flags)
        .SelectMany(p => new[] {p}.Concat(GetTypes(p.PropertyType)))
        .ToList();

    return result;
}
Community
  • 1
  • 1
M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118
  • I have two problems 1- does not work on .NET Core 2- your code can not get inner types of Dictionary, Array, Tuple, List, Collection and ... – HamedFathi Feb 18 '17 at 09:00
  • by inner types you mean generic types? it can be accessed by this property. `type.GenericTypeArguments`. for example for `Dictionary` it will give two types `long` and `float` in array. if given type is not generic this array is empty. note that in the solution I give you can access this property with this `propertyInfo.PropertyType.GenericTypeArguments`. – M.kazem Akhgary Feb 18 '17 at 09:38
  • what do you mean it does not work on .NET core 2, what error do you get? – M.kazem Akhgary Feb 18 '17 at 09:39
  • I know how access to any type I dont know how write it recursively !!! see this example : Tuple,Tuple>>,DateTime,List>> – HamedFathi Feb 18 '17 at 10:24