C# 递归地获取用属性标记的属性
在做了很多尝试和研究之后,我想问一下C# 递归地获取用属性标记的属性,c#,reflection,C#,Reflection,在做了很多尝试和研究之后,我想问一下 class Customer { [Foo] public string Name {get;set;} public Account Account {get;set;} } class Account { [Foo] public string Info {get;set;} } 我正在尝试获取标记有[Foo]属性的所有属性 我做了一些递归,但放弃了。以下是我尝试过的: public static IEnumer
class Customer
{
[Foo]
public string Name {get;set;}
public Account Account {get;set;}
}
class Account
{
[Foo]
public string Info {get;set;}
}
我正在尝试获取标记有[Foo]
属性的所有属性
我做了一些递归,但放弃了。以下是我尝试过的:
public static IEnumerable<PropertyInfo> GetPropertiesRecursive(this Type type)
{
var visitedProps= new HashSet<string>();
IList<PropertyInfo> propertyInfos = new List<PropertyInfo>();
var currentTypeInfo = type.GetTypeInfo();
while (currentTypeInfo.AsType() != typeof(object))
{
var unvisitedProperties = currentTypeInfo.DeclaredProperties.Where(p => p.CanRead &&
p.GetMethod.IsPublic &&
!p.GetMethod.IsStatic &&
!visitedProps.Contains(p.Name));
foreach (var propertyInfo in unvisitedProperties)
{
visitedProps.Add(propertyInfo.Name);
propertyInfos.Add(propertyInfo);
}
currentTypeInfo = currentTypeInfo.BaseType.GetTypeInfo();
}
return propertyInfos;
}
公共静态IEnumerable GetPropertiesRecursive(此类型)
{
var visitedProps=newhashset();
IList propertyInfos=新列表();
var currentTypeInfo=type.GetTypeInfo();
while(currentTypeInfo.AsType()!=typeof(对象))
{
var unvisitedProperties=currentTypeInfo.DeclaredProperties.Where(p=>p.CanRead&&
p、 GetMethod.IsPublic&&
!p.GetMethod.IsStatic&&
!visitedProps.Contains(p.Name));
foreach(未访问属性中的var propertyInfo)
{
visitedProps.Add(propertyInfo.Name);
propertyInfos.Add(propertyInfo);
}
currentTypeInfo=currentTypeInfo.BaseType.GetTypeInfo();
}
归还财产;
}
您可以使用此
更新了关于
下面是递归收集所有属性的工作代码示例: 它可以写得更好,但它展示了想法,完成了工作,填补了收藏:
List<PropertyInfo> _props = new List<PropertyInfo>();
List_props=newlist();
命名空间WpfApplication3
{
///
///MainWindow.xaml的交互逻辑
///
///
类MyClass
{
[属性类型]
公共字符串SomeString{get;set;}
公共MySecondClass MySecondClass{get;set;}
}
类MySecondClass
{
[属性类型]
公共字符串SomeString{get;set;}
}
类AttributeType:属性
{
}
公共部分类主窗口:窗口
{
公共主窗口()
{
CollectProperties(typeof(MyClass));
初始化组件();
}
列表_props=新列表();
公共属性(类型myType)
{
IEnumerable properties=myType.GetProperties()。其中(
property=>Attribute.IsDefined(property,typeof(AttributeType));
foreach(属性中的var propertyInfo)
{
如果(!_props.Any((pr=>pr.DeclaringType.FullName==propertyInfo.DeclaringType.FullName)))
{
_props.Add(propertyInfo);
}
}
var props=myType.GetProperties();
foreach(道具中的var propertyInfo)
{
CollectProperties(propertyInfo.PropertyType);
}
}
}
}
您想要这些属性的值,还是只想要一个属性列表,我在其他地方获取值。因此,只需列出PropertyInfo
您只需要每个具有给定属性的PropertyInfo
对象,还是还需要根对象到属性的路径(在多层嵌套的情况下)?我还需要路径。true
参数查找继承的属性。这不适用于属性(其文档化),如果要继承属性(或将参数设置为false),则需要使用Attribute.GetCustomAttributes
。我会使用GetCustomAttributes
的通用形式,可以说这更容易让人看到。另外,我认为您需要保留一个访问类型的列表,否则您可能会无限递归。这也找不到根对象的路径(root.Prop1.Prop2.Prop3)…我认为这可能是个棘手的问题party@pinkfloydx33在所有情况下,这只是在等待stackoverflow异常
foreach (var result in GetAttributeList<FooAttribute>(typeof(Customer)))
Console.WriteLine($"{result.Class} {result.Property.Name}");
ConsoleApp.Customer Name
ConsoleApp.Account Info
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);
}
}
}
}