簡體   English   中英

C# 派生類的 AllowMultiple 屬性

[英]C# AllowMultiple Attributes on Derived Classes

考慮下面的代碼片段:

[AttributeUsage(AttributeTargets.Class, AllowMultiple =true)]
public class FooAttribute : Attribute {
    public string Bar { get; set; } 
}

[Foo(Bar = "A")]
public class A{}

[Foo(Bar = "B")]
public class B : A{}

[Foo(Bar = "C")]
public class C : B{}

如果我嘗試獲取C類的FooAttribute

var attrList = typeof(C).GetCustomAttributes(typeof(FooAttribute), true) as FooAttribute[];

我將獲得所有 3 個屬性。 順序是C, B, A 所以這里是我的問題:

  • 這個順序是否是一種有保證的行為,這意味着派生類的屬性總是出現在比其基類更小的索引處?
  • 是否可以知道屬性附加到哪種特定類型?

通常不保證順序,編譯器會根據平台、文化和編譯器版本產生不同的結果。 然而,在這個特定場景中,它保證是正確的順序(至少部分)。 例外是當您在同一繼承級別分配多個屬性時:

[AttributeUsage(AttributeTargets.Class, AllowMultiple =true)]
public class FooAttribute : Attribute {
    public string Bar { get; set; } 
}

[Foo(Bar = "A")]
public class A{}

[Foo(Bar = "B"), Foo(Bar = "C")]
public class B : A{}

A(最后一個)的順序總是相同的,但 B 和 C 可以不同: CB -A 或BC -A。 在以下示例中,根本無法保證順序:

[Foo(Bar = "A"), Foo(Bar = "B"), Foo(Bar = "C")]
public class A{}

但是,如果您為每一級繼承分配一個屬性,則順序將保持不變。 這是由於 .NET(框架)中的實現,因為它遍歷每個基類型以收集所有屬性(如果您Type.GetCustomAttributes(Type, inherit: true) )。 這可以在這部分代碼( System.Private.CoreLibSystem.Reflection )中看到:

private static Attribute[] InternalGetCustomAttributes(EventInfo element, Type type, bool inherit)
{
    [...]

    // walk up the hierarchy chain
    Attribute[] attributes = (Attribute[])element.GetCustomAttributes(type, inherit);
    if (inherit)
    {
        // create the hashtable that keeps track of inherited types
        Dictionary<Type, AttributeUsageAttribute> types = new Dictionary<Type, AttributeUsageAttribute>(11);
        // create an array list to collect all the requested attibutes
        List<Attribute> attributeList = new List<Attribute>();
        CopyToArrayList(attributeList, attributes, types);

        EventInfo? baseEvent = GetParentDefinition(element);
        while (baseEvent != null)
        {
            attributes = GetCustomAttributes(baseEvent, type, false);
            AddAttributesToList(attributeList, attributes, types);
            baseEvent = GetParentDefinition(baseEvent);
        }
        Attribute[] array = CreateAttributeArrayHelper(type, attributeList.Count);
        attributeList.CopyTo(array, 0);
        return array;
    }
    else
        return attributes;
}

請注意,這是針對events但對於MemberInfo ( Type ) 也是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM