0

我需要获得PropertyDescriptorCollection所有用自定义属性装饰的属性。问题是TypeDescriptor.GetProperties只能通过所有属性的属性的精确匹配进行过滤,所以如果我想获得所有属性,无论属性的属性如何设置,我都必须涵盖过滤器数组中的所有可能性。

这是我的属性的代码:

[AttributeUsage(AttributeTargets.Property)]
class FirstAttribute : Attribute
{
    public bool SomeFlag { get; set; }
}

还有一个具有装饰属性的类:

class Foo
{
    [First]
    public string SomeString { get; set; }

    [First(SomeFlag = true)]
    public int SomeInt { get; set; }
}

主要:

static void Main(string[] args)
{
    var firstPropCollection = TypeDescriptor.GetProperties(typeof(Foo), new Attribute[] {new FirstAttribute()});
    Console.WriteLine("First attempt: Filtering by passing an array with a new FirstAttribute");
    foreach (PropertyDescriptor propertyDescriptor in firstPropCollection)
    {
        Console.WriteLine(propertyDescriptor.Name);
    }

    Console.WriteLine();
    Console.WriteLine("Second attempt: Filtering by passing an an array with a new FirstAttribute with object initialization");
    var secondPropCollection = TypeDescriptor.GetProperties(typeof(Foo), new Attribute[] { new FirstAttribute {SomeFlag = true} });
    foreach (PropertyDescriptor propertyDescriptor in secondPropCollection)
    {
        Console.WriteLine(propertyDescriptor.Name);
    }

    Console.WriteLine();
    Console.WriteLine("Third attempt: I am quite ugly =( ... but I work!");
    var thirdCollection = TypeDescriptor.GetProperties(typeof(Foo)).Cast<PropertyDescriptor>()
        .Where(p => p.Attributes.Cast<Attribute>().Any(a => a.GetType() == typeof(FirstAttribute)));
    foreach (PropertyDescriptor propertyDescriptor in thirdCollection)
    {
        Console.WriteLine(propertyDescriptor.Name);
    }

    Console.ReadLine();
}

到目前为止,我使它工作的唯一方法是第三次尝试,不知道是否有更直观和优雅的方法。

输出如下:

在此处输入图像描述

如您所见,我只能通过最后一次尝试获得这两个属性。

4

1 回答 1

1

我不确定我是否理解问题......您想要所有具有特定属性的属性,而不管此属性值如何?

class Program
{
    static void Main(string[] args)
    {
        var props = typeof(Foo).GetProperties();
        var filtered = props
            .Where(x => x.GetCustomAttributes(typeof(FirstAttribute), false).Length > 0)
            .ToList();
        var propertyDescriptor = TypeDescriptor.GetProperties(typeof(Foo))
            .Find(filtered[0].Name, false);
    }
}
class Foo
{
    [First]
    public string SomeString { get; set; }

    [First(SomeFlag = true)]
    public int SomeInt { get; set; }
}
[AttributeUsage(AttributeTargets.Property)]
class FirstAttribute : Attribute
{
    public bool SomeFlag { get; set; }
}
于 2017-08-01T16:01:46.427 回答