【发布时间】:2019-06-13 15:35:53
【问题描述】:
我正在构建一个属性搜索解决方案,它允许用户在事先不知道名称的嵌套属性列表中查找每个属性名称和值。在运行时唯一已知的类对象是父类。在下面的示例中,我将父对象(atype)传递给一个方法,该方法返回(所需)所有父子成员键和值的字典。
假设:每个父类都有多个嵌套类。在下面,Parent 是 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 方法的修改版本。我使用希思的子属性查找方法来获得第二级。这在第二级完美运行。仍然需要 - 递归搜索在每个 Child 中找到的潜在子类的选项。
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;
}
【问题讨论】:
-
如果我理解您要做什么,您可以检索属性
var value = GetPropertyValue(atype, prp.Name);的值,然后使用该值递归调用您的方法 (DictionaryFromType(value)),最后合并结果字典到父目录
标签: c# reflection properties