【问题标题】:PropertyInfo From SubClass property来自子类属性的 PropertyInfo
【发布时间】:2013-10-21 06:52:45
【问题描述】:

我有两个班级:

public class LookUpData 
{
  [Searchable]
  public string ManufactureName {get;set;)
}

public class Car
{
   public int ID {get;set;}
   [Searchable]  
   public string  Model {get;set;}
   public int ManufactureId {get;set;} 
   public LookUpData LookUpData{ get;set;} 

}

使用 [Searchable] 属性,我正在尝试获取属性,之后我可以在 DB 中进行搜索。

目前我有静态方法:

public static List<PropertyInfo> GetSearchPropertiesWithOrderBy(Type type)
{
  if (type == null) throw new ArgumentNullException("type");

  return type.GetProperties()
             .Select(x => new
                            {
                              Property = x,
                              Attribute =
                            (SearchableAttribute) Attribute.GetCustomAttribute(x, typeof (SearchableAttribute), true)
                            })
             .OrderBy(x => x.Attribute != null ? x.Attribute.OrderBy : 200)
             .Select(x => x.Property)
             .ToList();
}

我可以得到一个 PropertyInfo 的列表

 - Model 
 - LookUpData

如何获取 PropertyInfo 的列表以具有“真实姓名”属性:

 - Model   
 - ManufacterName

提前致谢。

【问题讨论】:

  • 真实姓名是什么意思?
  • 子类“LookUpData”的属性名称应为“ManufacterName”

标签: c# reflection custom-attributes propertyinfo


【解决方案1】:

这将适用于您的所有类如果层次结构也是一级、二级、三级、四级等。唯一缺少的是 OrderBy。我相信一旦获得清单,您就可以完成这件作品。

    public static List<PropertyInfo> GetSearchProperties(Type type)
    {
        if (type == null) throw new ArgumentNullException("type");


        List<PropertyInfo> propL = new List<PropertyInfo>();
        foreach (var item in type.GetProperties())
        {
            object[] obj = item.GetCustomAttributes(typeof(Searchable), true);
            if (obj.Count() > 0)
            {
                propL.Add(item);
            }
            else
            {                    
                propL.AddRange(GetSearchPropertiesWithOrderBy(item.PropertyType));
            }
        }
        return propL;        
    }
    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class Searchable : System.Attribute
    {

    }
    public class LookUpData
    {
        [Searchable]
        public string ManufactureName { get; set; }
    }

    public class Car
    {
        public int ID { get; set; }
        [Searchable]
        public string Model { get; set; }
        public int ManufactureId { get; set; }
        public LookUpData LookUpData { get; set; }

    }

使用层次结构意味着如果您的 LookUpData 属性没有直接在 Car 类中声明,例如,那么这段代码也可以正常工作。

    public class MyDataModels
    {
        LookUpData MysetOfData { get; set; }
        int MyVal { get; set; }
    }

    public  class MyCar
    {
        public int ID { get; set; }
        [Searchable]
        public string Model { get; set; }
        public int ManufactureId { get; set; }
        public MyDataModels MyModel { get; set; }

    }

【讨论】:

  • 所有单元测试也都通过了。有些失败了,但你的代码没问题,我的单元测试做错了。谢谢
【解决方案2】:

根据您的澄清评论,您希望为嵌套实例提供其属性的名称。如果您不想使用其属性名称来命名包含实例的属性,请尝试以下操作。

给定以下 SearchableAttribute:

public class SearchableAttribute : Attribute
{
    public int OrderBy { get; set; }

    public string SearchablePropertyName { get; set; }
}

你应该递归地提取属性的属性(这是一种深度优先的方法,你也可以这样做广度优先):

private static SearchableAttribute GetNestedSearchableAttribute(PropertyInfo propertyInfo)
{
    var attribute = (SearchableAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(SearchableAttribute), true);
    if (attribute == null)
    {
        return propertyInfo
            .PropertyType
            .GetProperties()
            .Select(GetNestedSearchableAttribute)
            .FirstOrDefault(attrib => attrib != null);
    }

    attribute.SearchablePropertyName = propertyInfo.Name;

    return attribute;
}

您不仅返回 PropertyInfo,还返回一个信息和描述,如下所示:

public static List<Tuple<PropertyInfo, string>> GetSearchPropertiesWithOrderBy(Type type)
{
    if (type == null)
        throw new ArgumentNullException("type");

    return type
        .GetProperties()
        .Select(
            x =>
            {
                var searchableAttribute = GetNestedSearchableAttribute(x);
                var description = new
                {
                    Property = x,
                    Attribute = searchableAttribute,
                    Name = searchableAttribute == null ? x.Name : searchableAttribute.SearchablePropertyName
                };

                return description;

            })
        .OrderBy(x => x.Attribute != null ? x.Attribute.OrderBy : 200)
        .Select(x => Tuple.Create(x.Property, x.Name))
        .ToList();
}

希望这就是你所需要的。

【讨论】:

  • 工作就像一个魅力。感谢您的帮助
【解决方案3】:

试试

.Select(x => new
             {
                 Property = x.Name,
                 ...

【讨论】:

    【解决方案4】:

    您也可以使用额外的递归方法来收集内部属性。

    像这样,

        public static void GetAllSearchPropertiesWithOrderBy(Type type, ref List<PropertyInfo> result)
        {
            result = result ?? new List<PropertyInfo>();
            foreach (var propertyInfo in GetSearchPropertiesWithOrderBy(type))
            {
                result.Add(propertyInfo);
                GetAllSearchPropertiesWithOrderBy(propertyInfo.PropertyType, ref result);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 2019-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      相关资源
      最近更新 更多