0

代码将显示这一切。你可以把它放到 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”没有以编程方式添加一个?
4

0 回答 0