Search code examples
c#reflectionrecursionnestednested-class

C# Reflection with recursion


I am working on the Reflection , but i am stuck while doing the recursion.

Code :

public class User {
  public string Name;
  public int Number;
  public Address Address;    
}


public class Address {
 public string Street;
 public string State;
 public string Country;
}

now i am printing the values.

 Type t = user.GetType();  
 PropertyInfo[] props = t.GetProperties(); 
 foreach (PropertyInfo prp in props)  
 {  
   if(!prp.GetType().IsPrimitive && prp.GetType().IsClass) 
   {
     // Get the values of the Inner Class.
     // i am stucked over here , can anyone help me with this.

           Type ty = prp.GetType();
           var prpI = ty.GetProperties();
           //var tp = ty.GetType().;
            foreach (var propertyInfo in prpI)
            {
            var value = propertyInfo.GetValue(prp);
            var stringValue = (value != null) ? value.ToString() : "";
            console.WriteLine(prp.GetType().Name + "." + propertyInfo.Name+" Value : " +stringValue);    
            }
   }
   else
   {    
     var value = prp.GetValue(user);   
     var stringValue = (value != null) ? value.ToString() : "";
     console.writeline(user.GetType().Name + "." + prp.Name+" Value : " +stringValue); 
   }
 }

i want to know how to find out whether the property is a class or the primitive. and do the recursion if it is a class.


Solution

  • First of all, if you want to access the properties of a type, ensure you are using a type which has properties:

    public class User {
      public string Name{get;set;}
      public int Number{get;set;}
      public Address Address{get;set;}    
    }
    
    
    public class Address {
     public string Street{get;set;}
     public string State{get;set;}
     public string Country{get;set;}
    }
    

    Second, prp.GetType() will always return PropertyInfo. You are looking for prp.PropertyType, which will return the Type of the property.

    Also, if(!prp.GetType().IsPrimitive && prp.GetType().IsClass) won't work the way you want, because String e.g. is a class and also not a primitive. Better use prp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary".

    Last but not least, to use recursion, you actually have to put your code into a method.

    Here's a complete example:

    IEnumerable<string> GetPropertInfos(object o, string parent=null)
    {
        Type t = o.GetType();  
        PropertyInfo[] props = t.GetProperties(BindingFlags.Public|BindingFlags.Instance);
        foreach (PropertyInfo prp in props)  
        {  
            if(prp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary")
            {
                // fix me: you have to pass parent + "." + t.Name instead of t.Name if parent != null
                foreach(var info in GetPropertInfos(prp.GetValue(o), t.Name))
                    yield return info; 
            }
            else
            {    
                var value = prp.GetValue(o);   
                var stringValue = (value != null) ? value.ToString() : "";
                var info = t.Name + "." + prp.Name + ": " + stringValue;
                if (String.IsNullOrWhiteSpace(parent))
                    yield return info; 
                else
                    yield return parent + "." + info; 
            }
        }
    }
    

    Used like this:

    var user = new User { Name = "Foo", Number = 19, Address = new Address{ Street="MyStreet", State="MyState",  Country="SomeCountry" }    };
    foreach(var info in GetPropertInfos(user))
        Console.WriteLine(info);
    

    it will output

    User.Name: Foo
    User.Number: 19
    User.Address.Street: MyStreet
    User.Address.State: MyState
    User.Address.Country: SomeCountry