Authoring Custom AttributesĀ 

Visual J# provides the ability to author custom .NET Framework Attributes. This is done by extending the .NET Framework Attribute class. For more information, see Attaching Attributes.

The declaration of a custom attribute is similar to the declaration of a class; however, the following rules apply:

  • Custom attributes must explicitly extend Attribute.

  • Custom attributes must use the predefined attribute AttributeUsageAttribute to define the characteristics of the attribute.

  • Named fields and properties in the attribute class must be public.

  • Custom attributes may not be inner classes.

  • Custom attributes may not be anonymous classes.

  • By convention, custom attribute classes should have names ending with "Attribute." When attaching the attribute, users of the attribute may omit the "Attribute" suffix.

Using the AttributeUsageAttribute

The AttributeUsageAttribute is used as follows:

/** @attribute System.AttributeUsage(
AttributeTargets.All,
Inherited = false,
AllowMultiple = true
) */

The first argument is the AttributeTargets enumeration which specifies which contexts the attribute is valid when used with. The following possible values are allowed. The bitwise OR operator may be used to specify a combination of targets.

Member Name Where the Attribute Can Be Attached

All

All program elements

Assembly

Assembly

Class

Class

Constructor

Constructor

Delegate

Delegate

Enum

Enum

Event

Event

Field

Field

Interface

Interface

Method

Method

Module

Module

Parameter

Parameter

Property

Property

Return

Return Value

Struct

User Defined Value Type

The second argument, Inherited, determines whether the attribute, if attached to a class, is inherited by classes extending the class to which it is applied.

The third argument, AllowMultiple, determines whether more than one instance of the attribute may be attached to the same entity. For more information, see Attaching Attributes.

Attribute classes have constructors, the arguments for which are supplied when the attribute is attached to a target. There are a few restrictions. Arrays that are 2D or greater may not be used in attribute constructor parameters; the parameters must be CLS-Compliant types. When attributes are used, the arguments must be constants.

Named Fields and Properties

Positional parameters are arguments for the attribute constructor. They are mandatory and must be specified every time an attribute is used. Named parameters are not defined on the attribute constructor; rather they are public fields or properties. Named parameters give the client the ability to set an attributes fields and properties when the attribute is instantiated. Each public CTOR can define a sequence of positional parameters (just as any type of class). However, in the case of attributes, once the positional parameters have been stated, the user can reference fields or properties with the following syntax:

FieldOrPropertyName=value

Remarks

Fields and properties that may be set in this manner must be public.

Disabling Attribute Authoring

Attribute authoring is disabled when the /x:net option is used.

Example

// CustomAttribute.jsl
import System.*;
import System.Diagnostics.*;

/** @attribute AttributeUsage(AttributeTargets.All,
                              Inherited = false,
                              AllowMultiple = false) */
public class OwnerAttribute extends System.Attribute
{
    private String m_owner;
    private String m_phone;

    public OwnerAttribute()
    {
      m_owner = "";
      m_phone = "";
    }

    public OwnerAttribute(String owner, String phone)
    {
       m_owner = owner;
       m_phone = phone;
    }

    /** @property */
    public String get_Owner()
    {
       return m_owner;
    }

    /** @property */
    public String get_Phone()
    {
       return m_phone;
    }   
}

/** @attribute Owner("JohnS", "555-3890") */
public class C1
{ }

/** @attribute Owner("EmilyK", "555-2121") */
public class C2 extends C1
{ }

class CMain
{

    public static void main()
    {
      C1 c1 = new C1();
      C2 c2 = new C2();
      OwnerAttribute oa = new OwnerAttribute();
      // GetCustomAttribute may be used to get attributes attached to a
      // type. The function takes two arguments of System.Type
      // representing the class type and the attribute type.
      oa = (OwnerAttribute) Attribute.GetCustomAttribute(c1.GetType(),
                                                         oa.GetType());
      Console.WriteLine("C1 Owner: {0} Phone: {1}", oa.get_Owner(),
                                                    oa.get_Phone());
      oa = (OwnerAttribute) Attribute.GetCustomAttribute(c2.GetType(),
                                                         oa.GetType());
      Console.WriteLine("C2 Owner: {0} Phone: {1}", oa.get_Owner(),
                                                    oa.get_Phone());
    }
}

Output

C1 Owner: JohnS Phone: 555-3890
C2 Owner: EmilyK Phone: 555-2121

See Also

Reference

Attaching Attributes
Syntax for Targeting the .NET Framework
Language Extensions to Support the .NET Framework