If I understand you correctly, you might need to use Reflection to retrieve the Address
objects:
public static class MyExtensions
{
public static List<Address> GetAddresses(this Dog dog)
{
var addresses = new List<Address>();
GetAddress(dog, ref addresses);
return addresses;
}
private static void GetAddress(object property, ref List<Address> addresses)
{
if (property == null)
{
return;
}
var props = property.GetType()
.GetProperties()
.Where(p => p.PropertyType.IsClass &&
!p.PropertyType.IsPrimitive)
.ToList();
foreach (var prop in props)
{
if (prop.PropertyType == typeof(Address))
{
var address = prop.GetValue(property) as Address;
addresses?.Add(address);
}
var next = prop.GetValue(obj: property);
// When property is a collection
if (next is IEnumerable collection)
{
foreach (var item in collection)
{
GetAddress(property: item,
addresses: ref addresses);
}
}
else
{
GetAddress(property: next,
addresses: ref addresses);
}
}
}
}
And usage example:
var dogs = new List<Dog>();
for (int i = 0; i < 5; i++)
{
var dog = new Dog
{
Name = $"Dog - {i}",
Age = 10,
Kennel = new Kennel
{
Address = new Address()
},
Kennels = new List<Kennel>
{
new Kennel
{
Address = new Address()
},
new Kennel
{
Address = new Address()
},
new Kennel()
{
Address = new Address()
}
},
Owner = new Owner
{
Address = new Address(),
Kennel = new Kennel
{
Address = new Address()
}
}
};
dogs.Add(dog);
}
var address = dogs.Select(dog => dog.GetAddresses());
Console.WriteLine(address.Sum(a => a.Count)); // will print 30
Please note that using Reflection could affect the performance of your application.