Using reflection to recursively read properties

I'm currently working on code that needs to retrieve the values of certain properties in an object recursively, without knowing the type of the object. So using reflection is required.

For demonstration, I'm using these two classes:

public class TestItem
{
    public string Name { get; set; } = string.Empty;
}

public class Test
{
    public string Name { get; set; } = string.Empty;
    public List<TestItem> Items { get; set; } = new();
}

And create instances of them:

var testInstance = new Test();
testInstance.Name = "Camera";

testInstance.Items.Add(new() { Name = "Microphone jack" });
testInstance.Items.Add(new() { Name = "Hotshoe" });
testInstance.Items.Add(new() { Name = "Bayonet" });

Finally, here is the method that recursively retrieves the values of the Name property:

using System.Diagnostics;
using System.Reflection;

public string[] GetNameValues(object obj, string propertyName)
{
    List<string> retVal = new();
    var objProperties = obj.GetType().GetProperties();

    foreach (var prop in objProperties)
    {
        var propVal = prop.GetValue(obj);
        if (propVal == null) {
            Debug.WriteLine($"Skipping property \"{prop.Name}\" with null value");
        }

        if (prop.Name == "Name") {
            Debug.WriteLine($"Found property named \"{propertyName}\"");
            retVal.Add(propVal.ToString());
        } else if (typeof(string) != prop.PropertyType && typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)) {
            Debug.WriteLine($"Property \"{prop.Name}\" is enumerable");
            
            foreach (var item in (IEnumerable)propVal)
            {
                retVal.AddRange(GetNameValues(item, propertyName));
            }
        }
    }

    return retVal.ToArray();
}

Calling the above method yields the following return:

index value
0 Camera
1 Microphone jack
2 Hotshoe
3 Bayonet

And writes the following to the debug console:

Found property named "Name"
Property "Items" is enumerable
Found property named "Name"
Found property named "Name"
Found property named "Name"
Marcel Diskowski

Marcel Diskowski