Я создаю решение поиска свойств, которое позволит пользователю искать каждое имя свойства и значение в списке вложенных свойств, имена которых заранее не известны. Единственный объект класса, известный во время выполнения, является родительским классом. В приведенном ниже примере я передаю родительский объект (atype) методу, который возвращает (желательно) словарь всех ключей и значений родительских и дочерних элементов.
Предположение: каждый родительский класс имеет несколько вложенных классов. В приведенном ниже поле Родитель имеет тип. Детям проще извлекать свойства родительского уровня с простыми типами, но не свойства вложенного класса, когда имена свойств свойств вложенного класса не известны во время выполнения.
Единственное решение, которое я нашел, - это опция поиска свойств, когда полный путь к классу известен во время выполнения. Это не вариант, когда класс содержит несколько классов с неизвестными свойствами. Некоторые из вложенных классов содержат другие свойства класса со своим собственным набором полей и свойств. Таким образом, нельзя делать предположения о глубине класса.
Желаемый: Предоставить возможность поиска родительского и всех вложенных классов без предварительного знания имен свойств вложенных классов.
public static Dictionary<string, object> DictionaryFromType(object atype)
{
if (atype == null) return new Dictionary<string, object>();
var t = atype.GetType();
var props = t.GetProperties();
var dict = new Dictionary<string, object>();
foreach (var prp in props)
{
if (prp.PropertyType.IsClass)
{
// The property Names of the Nested Class are not known at
// this point. This is an example.
// At this point I only know the property is a class.
// Passing the property class name yields no result.
var nestedValue = GetPropertyValue(atype, "childClass.nameField");
if (nestedValue != null)
dict.Add(prp.Name, nestedValue);
}
var value = GetPropertyValue(atype, prp.Name);
if (value != null)
dict.Add(prp.Name, value);
}
return dict;
}
Нижеследующее прекрасно работает, когда предоставлены соответствующий объект и вложенность. Он не пытается искать вложенный объект, в котором указано только имя объекта.
public static object GetPropertyValue(object obj, string propertyName)
{
var propertyNames = propertyName.Split('.');
foreach (string t in propertyNames)
{
if (obj != null)
{
var propertyInfo = obj.GetType().GetProperty(t);
if (propertyInfo != null)
obj = propertyInfo.GetValue(obj);
else
obj = null;
}
}
return obj;
}
Ниже приведена модифицированная версия моего метода DictionaryFromType. Я использовал метод поиска детского свойства Хита, чтобы получить второй уровень. Это прекрасно работает на втором уровне. Все еще желательно - возможность рекурсивного поиска среди потенциальных дочерних классов, найденных в каждом из них.
public static Dictionary<string, object> DictionaryFromType(object atype)
{
if (atype == null) return new Dictionary<string, object>();
var t = atype.GetType();
var props = t.GetProperties();
var dict = new Dictionary<string, object>();
try
{
foreach (var prp in props)
{
if (prp.PropertyType.IsClass)
{
// The property Names of the Nested Class are not known at this point
var nestedValue = GetNestedPropertyValue(atype, prp.Name);
if (nestedValue == null) continue;
var childType = nestedValue.GetType();
// Loop through the first Sub Class of child properties
// If this level is a Class, no properties will be returned.
// Still Needed: A way to loop through Children of Children to see if the the Property is a Class
foreach (var property in childType.GetProperties())
{
var childTypePropertyValue = GetPropertyValue(atype, prp.Name + "." + property.Name);
if (!dict.ContainsKey(property.Name) && !dict.ContainsValue(childTypePropertyValue))
{
dict.Add(property.Name, childTypePropertyValue);
}
}
}
else
{
var value = GetPropertyValue(atype, prp.Name);
if (value != null)
if (!dict.ContainsKey(prp.Name) && !dict.ContainsValue(value))
{
dict.Add(prp.Name, value);
}
}
}
return dict;
}
catch (Exception ex)
{
Log.Error("Error Building Dictionary : " + ex.Message);
}
return null;
}