Я думаю, что вы хотите что-то вроде этого:
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);
}
}
код не тестировался, но в принципе, вы хотите решать перечисляемые типы по-разному, по сравнению со скалярными значениями, так как только вы нажмете что-то типа IEnumerable<TItemType>
, вы делаете вызов метода FormatList<TPlaceholder>
.
Теперь имейте в виду, что ваши оригинальные T
и TItemType
не обязательно совпадают. Когда вы вызываете FormatList с использованием отражения, вы хотите привязать TPlaceholder
к TItemType
. Как только вы это сделали, вы просто вызываете метод форматирования и передаете ему фактический экземпляр списка, который возвращает вам строку. Затем эту строку вы можете просто вывести.
Надеюсь, что это поможет.
Почему этот метод общий (с '' параметра типа) и вы никогда не используя 'T' для чего-нибудь? –
@HighCore, который он мог бы сделать 'PrintReturnedProperties (подкласс);' –
Вы должны использовать имя параметра, отличное от 'Object', чтобы избавиться от путаницы со встроенным объектом/объектом. –