Чтобы получить значение для вложенного члена, который может быть в коллекции, необходимо выполнить итерацию коллекций и отслеживать текущий объект.
Предполагая, что вам не нужен полученный PropInfo
по другим причинам просто попробуйте получить значение:
private static bool TryRecursiveGetValueWithMyDBFieldName(object startObject, string attribName, out object propValue) {
PropertyInfo[] pi = startObject.GetType().GetProperties();
foreach (PropertyInfo p in pi) {
var dbFieldAttribute = (MyDBFieldAttribute)Attribute.GetCustomAttribute(p, typeof(MyDBFieldAttribute));
if (dbFieldAttribute != null && dbFieldAttribute.Name.Equals(attribName, StringComparison.CurrentCultureIgnoreCase)) {
//Console.WriteLine(p.Name + " : " + (dbFieldAttribute != null && dbFieldAttribute.Name != null ? dbFieldAttribute.Name : "****"));
propValue = p.GetValue(startObject);
return true;
}
if (p.PropertyType.IsClass && !p.PropertyType.IsValueType && !p.PropertyType.IsPrimitive &&
!p.PropertyType.FullName.StartsWith("System.")) {
var tryObject = p.GetValue(startObject);
if (tryObject != null && TryRecursiveGetValueWithMyDBFieldName(tryObject, attribName, out propValue))
return true;
}
if (p.PropertyType.IsClass && p.GetValue(startObject) is IEnumerable ip) {
foreach (var obj in ip) {
if (obj != null && TryRecursiveGetValueWithMyDBFieldName(obj, attribName, out propValue))
return true;
}
}
}
propValue = default;
return false;
}
Чтобы использовать его, вызовите с начальным объектом:
var foundAttrib = TryRecursiveGetValueWithMyDBFieldName(planet, "NeighborRing", out var propValue);
ПРИМЕЧАНИЕ. Это вернет значение первого объекта с соответствующим атрибутом, как, например, каждый член List<Neighbor>
будет иметь атрибут MyDBField
со свойством Name
NeighborRing
.