我正在构建一个属性搜索解决方案,该解决方案将允许用户在嵌套属性列表中查找每个属性名称和值,而这些属性和属性的名称事先都不知道。在运行时唯一已知的类对象是父类。在下面的示例中,我将父对象(atype)传递给一个方法,该方法返回(期望)所有父子成员键和值的字典。
假设:每个父类都有多个嵌套类。在下面,父项是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;
}
答案 0 :(得分:0)
您知道属性类型是一个类(说实话,.NET中几乎所有内容都将是此类,包括String
),但是您首先需要反映该类型并枚举其属性,例如(基本示例;进行一些假设并省略为简洁起见的错误处理):
static object GetPropertyValue(object parent, string nestedPropertyName)
{
object propertyValue = null;
var tokens = nestedPropertyName.Split('.');
foreach (var token in tokens)
{
var property = parent.GetType().GetProperty(token, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
propertyValue = property.GetValue(parent);
if (propertyValue is null) return null;
parent = propertyValue;
}
return propertyValue;
}