Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 递归地获取用属性标记的属性_C#_Reflection - Fatal编程技术网

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);
            }
        }
    }
}