Search code examples
c#recursionreflectionwhere-clausetype-constraints

C# Recursion using reflection on a where type constraint


I'm trying to do recursion through a class but I can't see how I can invoke it with a type constraint.

My problem is mainly I don't know how to invoke the recursion and pass the property type on the Analyze call.

Here's my code:

public class recursor 
{
    public string Analyze<T>() where T : class, new() 
    {
        StringBuilder sb = new StringBuilder();

        T t = new T();

        var propList = t.GetType().GetProperties();

        foreach (var prop in propList)
        {
            System.TypeCode propertyTypeCode = Type.GetTypeCode(prop.PropertyType);

            if (prop.PropertyType.IsClass)
            {
                // THIS IS WHAT I CAN'T FIGURE IT OUT
                // sb.Append(this.Analyze());
            }
            else
            {
                sb.Append("not a class");
            }
        }

        return sb.ToString();
    }
}

public class A {}

public class B {}

public class C {}
  
public class _container 
{
    public A _a;
    public B _b;
    public C _c;
}

public void main() 
{
   var r = new recursor();
   var s = r.Analyze<_container>();
}

Solution

  • This should help you to move on:

    public class recursor
    {
    public string Analyze<T>() where T : class
    {
        StringBuilder sb = new StringBuilder();
    
        var propList = typeof(T).GetProperties();
    
        foreach (var prop in propList)
        {
            System.TypeCode propertyTypeCode = Type.GetTypeCode(prop.PropertyType);
            if (prop.PropertyType.IsClass)
            {
                sb.Append(this.GetType().GetMethod("Analyze").MakeGenericMethod(prop.PropertyType).Invoke(this, null).ToString());
                sb.Append(prop.Name);
            }
            else
            {
                sb.Append("not a class");
            }
        }
        return sb.ToString();
    }    
    
    public class A { }
    public class B { }
    public class C { }
    
    public class _container
    {
        public A _a { get; set; }
        public B _b { get; set; }
        public C _c { get; set; }
    }
    

    That produces _a_b_c for me.

    It's recursing and getting a result. You'll need to make sense of it for what you need.


    Here's an entirely better version of the method:

    public string Analyze2<T>() where T : class
        => this.Analyze2(typeof(T));
    
    public string Analyze2(Type type)
        => String.Concat(
            type
                .GetProperties()
                .Select(p =>
                    p.PropertyType.IsClass
                    ? this.Analyze2(p.PropertyType)
                    : "not a class"));