Разве не подойдет следующее?
public static IEnumerable<PropertyInfo> GetProperties(this Type type, int depth = 1)
{
IEnumerable<PropertyInfo> getProperties(Type currentType, int currentDepth)
{
if (currentDepth >= depth)
yield break;
foreach (var property in currentType.GetProperties())
{
yield return property;
foreach (var subProperty in getProperties(property.PropertyType,
currentDepth + 1))
{
yield return subProperty;
}
}
}
if (depth < 1)
throw new ArgumentOutOfRangeException(nameof(depth));
return getProperties(type, 0);
}
Дан следующий тип:
class Foo
{
public string S { get; }
public int I { get; }
}
Выход
Console.WriteLine(string.Join(Environment.NewLine,
typeof(Foo).GetProperties(2)
.Select(p => $"{p.DeclaringType.Name}: {p.Name}")));
будет:
Foo: S
String: Chars
String: Length
Foo: I