Fetch and print all properties of an object graph as string Below I have setup an extension method that takes any object, cycles through its properties, and prints each out to a Console window in the format Name: Value.


  Specification / Scope:
  
  
  Handle only single objects (no collections)
  


code

public static string PropertiesToString&lt;T&gt;(this T obj, int tabs = 0) where T : class
{
    int initTabs = tabs;
    string result = string.Empty;
    PropertyInfo[] propertyInfo = obj.GetType().GetProperties();
    foreach (PropertyInfo property in propertyInfo)
    {
        string name = property.Name;
        object value = property.GetValue(obj, null);
        Type valueType = value.GetType();
        if (valueType.IsValueType || valueType.Name.Equals("String"))
        {
            for (int i = 0; i &lt; tabs; i++)
            {
               result += "    ";
            }
            result += string.Format("{0}: {1}\n", name, value == null ? string.Empty : value.ToString());
        }
        else
        {
            result += string.Format("{0}:\n", name);
            result += value.PropertiesToString(++tabs);
        }
        tabs = initTabs;
    }
   return result;
}


Here is a class I'm using to test this code, along with the lines responsible for creating an instance of the class and writing its properties to the Console:

Class:

public class Circle : IShape
{
    public Circle(double x, double y, double radius)
    {
        Center = new Point
        {
            X = x,
            Y = y
        };
        Radius = radius;
    }

    public Point Center { get; set; }
    public double Radius { get; set; }

    public double Area(int precision = 2)
    {
        return Math.Round(Radius * Radius * Math.PI, precision);
    }
}


Main:

public static void Main(string[] args)
{
    IShape circle = new Circle(5, 5, 10);
    Console.WriteLine(circle.PropertiesToString());
    Console.ReadLine();
}


The above method will also cycle through nested objects and print those to the Console as well, adding in tabs for readability's sake.

I'm kind of unfamiliar with System.Reflection and was wondering if there was a more efficient way I could approach doing something like this.
You should have a guard clause against someone passing in null 

PropertyInfo has a PropertyType and you should use that instead of 

 Type valueType = value.GetType();


as if value is null you will get a null reference error where PropertyType will give you the type of the property. 

You will need to fix this line as well if value is null.  Again you will get a null reference error

 result += value.PropertiesToString(++tabs);


Better to compare types then their names.  Instead of 

 valueType.Name.Equals("String")


use 

 valueType == typeof(string)


You should separate out gathering the properties and displaying them.  I would have an extension method that returned IEnumerable> and then you could use linq to convert that into the strings and how you want it displayed.  

Other things to consider is if you have two object that reference each other you will get a stack overflow.  

I would recommend looking at https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.objectmanager?view=netframework-4.8 to see an example of an object walker.  I think making the class IEnumerable is a bit confusion when learning and they would have been better making a method that returns IEnumerable.  still a good place to start when learning about walking an object graph.