Ogni compilatore è libero di ordinare l'elenco di attributi multi-use che decorano un elemento di codice in base alle sue proprie regole. In questo senso, le specifiche di C# avvertono: "The order in which attributes are specified in an attribute section, and the order in which sections attached to the same program entity are arranged, is not significant" (ECMA-334, 24.2).
I seguenti 3 snippet equivalenti, scritti rispettivamente in C#, VB e J#:
using System;
[Foo(1), Foo(2), Foo(3), Foo(4), Foo(5), Foo(6), Foo(7), Foo(8), Foo(9), Foo(10)]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
class FooAttribute : Attribute
{
public FooAttribute(int index)
{
_index = index;
}
private int _index;
public int Index
{
get
{
return _index;
}
}
static void Main()
{
Type fooAttributeType = typeof(FooAttribute);
foreach (FooAttribute attribute in fooAttributeType.GetCustomAttributes(fooAttributeType, false))
{
Console.WriteLine(attribute.Index);
}
}
}
Imports System
<Foo(1), Foo(2), Foo(3), Foo(4), Foo(5), Foo(6), Foo(7), Foo(8), Foo(9), Foo(10)> _
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=True)> _
Class FooAttribute
Inherits Attribute
Public Sub New(ByVal index As Integer)
_index = index
End Sub
Private _index As Integer
Public ReadOnly Property Index() As Integer
Get
Return _index
End Get
End Property
Shared Sub Main()
Dim fooAttributeType As Type = GetType(FooAttribute)
For Each attribute As FooAttribute In fooAttributeType.GetCustomAttributes(fooAttributeType, False)
Console.WriteLine(attribute.Index)
Next
End Sub
End Class
import System.*;
/** @attribute Foo(1) */
/** @attribute Foo(2) */
/** @attribute Foo(3) */
/** @attribute Foo(4) */
/** @attribute Foo(5) */
/** @attribute Foo(6) */
/** @attribute Foo(7) */
/** @attribute Foo(8) */
/** @attribute Foo(9) */
/** @attribute Foo(10) */
/** @attribute AttributeUsage(AttributeTargets.Class, AllowMultiple = true) */
class FooAttribute extends Attribute
{
public FooAttribute(int index)
{
_index = index;
}
private int _index;
/** @property */
public int get_Index()
{
return _index;
}
public static void main()
{
Type fooAttributeType = Type.GetType("FooAttribute");
Object[] attributes = fooAttributeType.GetCustomAttributes(fooAttributeType, false);
for (int i = 0; i < attributes.get_Count(); i++)
{
Console.WriteLine(((FooAttribute)attributes[i]).get_Index());
}
}
}
producono i seguenti risultati:
C# |
VB |
J# |
1 |
9 |
1 |
4 |
10 |
2 |
5 |
8 |
3 |
6 |
7 |
4 |
7 |
6 |
5 |
8 |
5 |
6 |
9 |
4 |
7 |
10 |
3 |
8 |
2 |
2 |
9 |
3 |
1 |
10 |
Tra i tre compilatori, solo quello per J# sembra che non cambi l'ordine. Importante è non presupporre alcun ordine nell'elenco di attributi multi-use in una decorazione.