首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将对象属性映射到字典的最有效方法,其中键使用扩展方法表示路径。

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

Stack Overflow用户
提问于 2012-06-07 15:48:14
回答 1查看 2.1K关注 0票数 1

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

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

使用反射是最好的方法吗?有例子吗?

谢谢Z..。

澄清最新情况

"ParentCompany.BillingAddress"字典键应该是基于属性名称的路径,而不是hierarchy.So类型,如果客户有属性public Company ParentCompany,而公司有属性public Address BillingAddress,那么键路径应该是public Company ParentCompany

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-07 16:21:56

编辑:

代码语言:javascript
复制
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;
        }
    }
}

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10935291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档