扩展方法将对象属性映射到IDictionary的最有效方法是:
使用反射最佳方法吗? 有一个例子吗?
由于 Z ...
public Company ParentCompany
且公司具有属性public Address BillingAddress
,则键路径应为“ParentCompany.BillingAddress”答案 0 :(得分:2)
修改强>
public static IDictionary<string, string> GetProperties<T>(this T obj)
where T : class
{
var properties = obj.GetPropertyList();
return properties.ToDictionary(prop => prop.Item1, prop => prop.Item2);
}
public static IEnumerable<Tuple<string, string>> GetPropertyList<T>(this T obj)
where T : class
{
if (obj == null)
throw new ArgumentNullException("obj");
Type t = obj.GetType();
return GetProperties(obj, t, t.Name);
}
private static IEnumerable<Tuple<string, string>> GetProperties(object obj, Type objType, string propertyPath)
{
// If atomic property, return property value with path to property
if (objType.IsValueType || objType.Equals(typeof(string)))
return Enumerable.Repeat(Tuple.Create(propertyPath, obj.ToString()), 1);
else
{
// Return empty value for null values
if (obj == null)
return Enumerable.Repeat(Tuple.Create(propertyPath, string.Empty), 1);
else
{
// Recursively examine properties; add properties to property path
return from prop in objType.GetProperties()
where prop.CanRead && !prop.GetIndexParameters().Any()
let propValue = prop.GetValue(obj, null)
let propType = prop.PropertyType
from nameValPair in GetProperties(propValue, propType, string.Format("{0}.{1}", propertyPath, prop.Name))
select nameValPair;
}
}
}
这仍然不处理值参数的默认值。请注意,何时停止递归迭代的逻辑是关键。最初我停在了值类型的属性,但这意味着字符串被视为与其他对象一样。所以我添加了一个特殊情况来将字符串视为原子类型。