Applying Attributes

 <  Day Day Up  >  

An instance of an attribute class is applied to a declaration by enclosing a constructor call in angle brackets ( <> ). Attributes always come before any regular modifiers. The following example applies the System.ThreadStaticAttribute attribute (which makes a Shared field's storage unique for each thread) to a field.

 Class Test   <ThreadStatic> Public Shared x As Integer End Class 

Style

Instead of using the full name of an attribute, such as System.ThreadStaticAttribute , for readability and simplicity you can leave off the "Attribute" suffix when applying the attribute.


Frequently, attribute constructors will have parameters that allow extra information to be specified as part of the attribute application. Arguments to an attribute follow the name of the attribute in parentheses, exactly as if they were constructor arguments. For example, the System.ObsoleteAttribute attribute (which is used to mark methods that are obsolete) takes a String as a parameter.

 <System.Obsolete("This API should not be called.")> _ Sub Test()   ... End Sub 

NOTE

Like language-defined modifiers, attributes have to be on the same source code line as the declaration that they modify. If you wish to put attributes on a separate line, you have to use a line continuation to connect the two lines into a single line.


Attributes also can have properties that can be used to store optional information. For example, the System.AttributeUsageAttribute attribute (which is used to define new attributes, as shown in the next section) has two properties, AllowMultiple and Inherited , which are optional values. Values are assigned to properties in the same way that named arguments are used in normal method invocation: The name of the property is followed by a colon equals ( := ) and the value. Like named arguments, properties must follow regular arguments in the argument list. The following code shows two uses of AttributeUsage , one with values set to the properties, one without.

 <System.AttributeUsage(AttributeTargets.All)> _ Class FirstAttribute   Inherits Attribute End Class <AttributeUsage(AttributeTargets.All, _                 AllowMultiple := True, _                 Inherited := False)> _ Class SecondAttribute   Inherits Attribute End Class 

Attributes can be placed anywhere that access modifiers, such as Public and Private , can be placed. In addition, attributes can be placed

  • On members of enumerations.

  • On parameters.

  • On individual property accessors (i.e., before the Get or Set ). In this case, the attribute applies to the underlying Get or Set method that the compiler generates for the property.

  • On the return type of a function.

  • On an assembly or .NET Framework module.

The last two points bear some discussion. Attributes may be placed on the return type of a function primarily so that COM marshalling in formation (using the System.Runtime.InteropServices.MarshalAsAttribute ) can be applied to function return types. The attribute is placed right before the function return type's name. For example, the following declaration applies an attribute to the return type of the function F .

 Imports System.Runtime.InteropServices Class Test   Function F() As <MarshalAs(UnmanagedType.I4)> Integer     ...   End Function End Class 

It is also possible to define attributes that apply to the assembly or .NET Framework module being produced by the compiler. (.NET Framework modules are a special type of assembly that can be linked together to produce a single assembly. Their usage is beyond the scope of this book.) To apply an attribute to the assembly or Framework module as a whole, you can specify an attribute by itself after any Option or Imports statements. The attribute name must be preceded by " assembly: " for attributes that apply to the assembly, or " module: " for attributes that apply to Framework modules. At compile time, all the attributes applied to the assembly or Framework module are combined. For example, the following code shows the usage of the System.Reflection.AssemblyDescriptionAttribute attribute.

 Imports System.Reflection <Assembly: AssemblyDescription("A test program.")> Module Test   Sub Main()     Console.WriteLine("Test.")   End Sub End Module 

Some attributes can be applied multiple times to a declaration. For example, the System.ObsoleteAttribute attribute can be applied only once, but the System.Diagnostics.ConditionalAttribute attribute (which allows method calls to be compiled on a conditional basis) can be applied multiple times.

 Module Test <Obsolete("Don't call this API."), _  Diagnostics.Conditional("DEBUG"), _  Diagnostics.Conditional("TEST")> _   Sub Main()     Console.WriteLine("Test.")   End Sub End Module 

Attributes applied to a class are, by default, inherited by any classes that derive from that class. Overriding a method does not remove the attributes applied to the method being overridden. If an overriding method specifies the same attribute as the method being overridden, the behavior depends on whether or not the attribute can be applied multiple times: If the attribute can be used multiple times, the overriding attribute complements the overridden attribute; if the attribute is single-use , the overriding attribute replaces the overridden attribute.

 <  Day Day Up  >  


The Visual Basic .NET Programming Language
The Visual Basic .NET Programming Language
ISBN: 0321169514
EAN: 2147483647
Year: 2004
Pages: 173
Authors: Paul Vick

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net