为什么TypeDescriptor.GetAttributes不返回所有属性?

时间:2019-08-19 16:46:22

标签: c# attributes typedescriptor

代码将全部显示。您可以将其放在RoslynPad或VS中。

using System.ComponentModel;

[AttributeUsage(AttributeTargets.Class, AllowMultiple=true, Inherited=true)]
class CategoryOrderAttribute : Attribute{

    public CategoryOrderAttribute(string category, int order){
        Category = category;
        Order    = order;
    }

    public string Category { get; }
    public int    Order    { get; }

    public override string ToString()
        => $"  Category:{Category}, Order:{Order}";
}

[CategoryOrder("Test", 1)]
[CategoryOrder("OtherTest", 2)]
public class TestClass{

    static TestClass(){

        var sb = new StringBuilder();

        var foundAttributesA = typeof(TestClass)
            .GetCustomAttributes(typeof(CategoryOrderAttribute), true)
            .OfType<CategoryOrderAttribute>();

        sb.AppendLine("Test A");
        foreach(var foundAttribute in foundAttributesA)
            sb.AppendLine(foundAttribute.ToString());

        var foundAttributesB = TypeDescriptor.GetAttributes(typeof(TestClass))
            .OfType<CategoryOrderAttribute>();

        sb.AppendLine("Test B");
        foreach(var foundAttribute in foundAttributesB)
            sb.AppendLine(foundAttribute.ToString());

        // Add new attribute programmatically
        TypeDescriptor.AddAttributes(typeof(TestClass),
            new CategoryOrderAttribute("AddedInCode", 42));

        var foundAttributesC = typeof(TestClass)
            .GetCustomAttributes(typeof(CategoryOrderAttribute), true)
            .OfType<CategoryOrderAttribute>();

        sb.AppendLine("Test C");
        foreach(var foundAttribute in foundAttributesC)
            sb.AppendLine(foundAttribute.ToString());

        var foundAttributesD = TypeDescriptor.GetAttributes(typeof(TestClass))
            .OfType<CategoryOrderAttribute>();

        sb.AppendLine("Test D");
        foreach(var foundAttribute in foundAttributesD)
            sb.AppendLine(foundAttribute.ToString());

        Console.WriteLine(sb.ToString());
    }
}

_ = new TestClass();
Console.WriteLine("Tests Done!");

输出如下:

Test A
  Category:Test, Order:1
  Category:OtherTest, Order:2
Test B
  Category:Test, Order:1
Test C
  Category:Test, Order:1
  Category:OtherTest, Order:2
Test D
  Category:AddedInCode, Order:42

所以我的问题是:

  1. 为什么只在“测试B”中获得第一个
  2. 为什么它只能以编程方式在“测试D”中添加一个?
  3. 为什么“测试C”无法以编程方式添加?

0 个答案:

没有答案