I think you want something like this:
public class Program
{
public static void PrintProperties<T>(T t)
{
var properties = t.GetType().GetProperties();
foreach (var property in properties)
{
var name = property.Name;
var value = property.GetValue(t, null);
if (property.PropertyType.IsGenericType && property.PropertyType == typeof(IEnumerable<>))
{
var formatList = typeof(Program).GetMethod("FormatList", new[] { value.GetType() });
// value.GetType().GetGenericArguments().First() will get you the underlying type of the list,
// i.e., the TItemType where the property you are currently
// handling is of type IEnumerable<TItemType>
formatList.MakeGenericMethod(value.GetType().GetGenericArguments().First());
value = formatList.Invoke(null, new object[] { value });
Console.Out.WriteLine(name + ": " + value);
}
else
{
Console.Out.WriteLine(name + ": " + value);
}
}
}
public static string FormatList<TPlaceholder>(IEnumerable<TPlaceholder> l)
{
return string.Join(", ", l);
}
}
The code is untested but basically, you want to tackle enumerable types differently as compared to scalar values, so once you hit something of the type IEnumerable<TItemType>
, you make a call to the FormatList<TPlaceholder>
method.
Now, bear in mind that your original T
and TItemType
are not necessarily the same. When you invoke FormatList using reflection, you want to bind the TPlaceholder
to TItemType
. Once you have done that, you just invoke the formatting method and pass it the actual instance of the list, which returns you a string. That string you can then just output.
Hope that helps.