将对象属性映射到字典的最有效方法,其中键表示使用扩展方法的路径

时间:2012-06-07 15:48:14

标签: c# reflection

扩展方法将对象属性映射到IDictionary的最有效方法是:

  • 键是属性路径(例如“Customer.Company.Address.Line1”)
  • 值是属性值的字符串表示(例如“123” 当为null或默认值时,主St.“或”“(空字符串)
  • 属性集合仍然只包含路径(例如 公共IList发票 - > “Customer.Invoices”,但价值是 收集计数)

使用反射最佳方法吗? 有一个例子吗?

由于 Z ...

澄清更新

  • 字典键应该是基于属性名称而不是类型层次结构的路径。如果客户具有属性public Company ParentCompany且公司具有属性public Address BillingAddress,则键路径应为“ParentCompany.BillingAddress”

1 个答案:

答案 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;
        }
    }
}

这仍然不处理值参数的默认值。请注意,何时停止递归迭代的逻辑是关键。最初我停在了值类型的属性,但这意味着字符串被视为与其他对象一样。所以我添加了一个特殊情况来将字符串视为原子类型。