递归获取带有属性标记的属性

时间:2018-10-28 09:14:29

标签: c# reflection

在进行了许多尝试和研究之后,想问问。

@Configuration
public class DatabaseConfiguration

我正在尝试获取标记有class Customer { [Foo] public string Name {get;set;} public Account Account {get;set;} } class Account { [Foo] public string Info {get;set;} } 属性的所有属性。

我做了一些递归但放弃了。这是我尝试过的:

[Foo]

2 个答案:

答案 0 :(得分:2)

您可以使用此

关于@pinkfloydx33

中评论的一些要点,

已更新

public static IEnumerable<(Type Class, PropertyInfo Property)> GetAttributeList<T>(Type type, HashSet<Type> visited = null)
   where T : Attribute
{

   // keep track of where we have been
   visited = visited ?? new HashSet<Type>();

   // been here before, then bail
   if (!visited.Add(type))
      yield break;

   foreach (var prop in type.GetProperties())
   {
      // attribute exists, then yield
      if (prop.GetCustomAttributes<T>(true).Any())
         yield return (type, prop);

      // lets recurse the property type as well
      foreach (var result in GetAttributeList<T>(prop.PropertyType, visited))
         yield return (result);
   }
}

用法

foreach (var result in GetAttributeList<FooAttribute>(typeof(Customer)))
   Console.WriteLine($"{result.Class} {result.Property.Name}");

输出

ConsoleApp.Customer Name
ConsoleApp.Account Info

答案 1 :(得分:2)

下面是一个工作代码示例,该示例递归收集所有属性: 它可以写得更好,但是可以显示出这个想法,可以完成工作并填充收藏集:

List<PropertyInfo> _props = new List<PropertyInfo>();

namespace WpfApplication3
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 

    class MyClass
    {
        [AttributeType]
        public string SomeString { get; set; }

        public MySecondClass MySecondClass { get; set; }
    }

    class MySecondClass
    {
        [AttributeType]
        public string SomeString { get; set; }
    }

    class AttributeType : Attribute
    {

    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            CollectProperties(typeof (MyClass));
            InitializeComponent();
        }

        List<PropertyInfo> _props = new List<PropertyInfo>();

        public void CollectProperties(Type myType)
        {
            IEnumerable<PropertyInfo> properties = myType.GetProperties().Where(
                property => Attribute.IsDefined(property, typeof(AttributeType)));


            foreach (var propertyInfo in properties)
            {
                if (!_props.Any((pr => pr.DeclaringType.FullName == propertyInfo.DeclaringType.FullName)))
                {
                    _props.Add(propertyInfo);
                }
            }


            var props = myType.GetProperties();

            foreach (var propertyInfo in props)
            {
                CollectProperties(propertyInfo.PropertyType);
            }
        }
    }
}