Built-in Attributes

You use attributes to connect metadata, including compiler directives, to an element in your code. There are plenty of attributes built into C#, and we've already seen a number of them in this book. For example, this attribute lets you indicate that a method is a Web method, accessible from a Web service:

 
 [WebMethod] 

This attribute lets you indicate that a class can be serialized:

 
 [Serializable] 

This attribute indicates that you want to import a DLL; in this case, kernel32.dll:

 
 [DllImport("kernel32", SetLastError=true)] 

Note the syntax in this case. We're passing text to the DLLImport attribute, followed by the expression SetLastError=true .

We also saw that you can use attributes to specify metadata about specific elements, as here, where we're setting the version and title of an assembly:

 
 [assembly:AssemblyVersion Attribute("1.0.0.0")] [assembly:AssemblyTitleAttribute("Example ch14_01")] 

ATTRIBUTES ARE CREATED WITH CLASSES

It probably won't surprise you to learn that attributes are created with classes in C#, and the values you pass to an attribute are passed to its constructor. Additional name = value pairs let you set the values of properties built into the attribute's class. More on this when we create our own custom attributes in a page or two.


Also note that the attributes here are prefixed with the text assembly: , which is an attribute target .

Specifying Attribute Targets

Sometimes, it might not be clear what the target of an attribute is. For example, if you use an attribute just before a method, does it apply to the method or to the assembly as a whole? To make sure that the target of an attribute is clear to the compiler, you can specify one of a set of predefined targets like this:

 
 [  target  :  attribute-list  ] 

Here are the parts of this attribute:

  • target The target of the attribute.

  • attribute-list A list of applicable attributes.

You can see the predefined targets for attributes, as defined in the AttributeTargets enumeration, in Table 14.1.

Table 14.1. Predefined Attribute Targets

DECLARATION

TARGET(S)

All

Any application element

Assembly

An assembly

Class

A class

Constructor

A constructor

Delegate

A delegate

Enum

An enumeration

Event

An event

Field

A field

Interface

An interface

Method

A method

Module

A module

Parameter

A parameter

Property

A property

ReturnValue

A return value

Struct

A structure (that is, a value type)

Conditional Attributes

Attributes can contain directives to the compiler, and one consequence of that is that besides standard attributes, you can also use conditional attributes . Conditional attributes are much like the preprocessor directives we saw in Chapter 1, "Essential C#," although they're designed exclusively for use in method declarations. These attributes determine whether a symbol has been defined, and if so, include the following code at compile time. Here's how you use them in general:

 
 [Conditional(  conditionalSymbol  )] 

In this case, conditionalSymbol is a symbol you can define with the #define preprocessor directive. Here's an example, the Debugger class, where we'll include code for use only when we're debugging. If you define a symbol you name DEBUGGING in this code (using the #define preprocessor directive), the method following the [Conditional] attribute, which displays a debugging message, is included at compile time:

 
  #define DEBUGGING  using System; using System.Diagnostics; public class Debugger {   [Conditional("DEBUGGING")] public static void Write(string text)   {    System.Console.WriteLine(text);   } } 

Now you can call Debugger.Write in other code; if DEBUGGING is defined, that method will display the text passed to it. If the #define DEBUGGING line is commented out, calling Debugger.Write won't display any text. You can see this at work in ch14_01.cs, Listing 14.1.

Listing 14.1 Creating a Custom Conditional Attribute (ch14_01.cs)
 #define DEBUGGING using System; using System.Diagnostics; public class Debugger {   [Conditional("DEBUGGING")] public static void Write(string text)   {    System.Console.WriteLine(text);   } } class ch14_01 {   static void Method1()   {  Debugger.Write("Now in Method1.");  Method2();   }   static void Method2()   {  Debugger.Write("Now in Method2.");  }   public static void Main()   {    Method1();    System.Console.WriteLine("Did it work?");   } } 

Here's what you see when you run ch14_01.cs as it appears in Listing 14.1:

 
 C:\>ch14_01 Now in Method1. Now in Method2. Did it work? 

If you comment out the #define DEBUGGING line in the code, you'll see this instead:

 
 C:\>ch14_01 Did it work? 


Microsoft Visual C#. NET 2003 Kick Start
Microsoft Visual C#.NET 2003 Kick Start
ISBN: 0672325470
EAN: 2147483647
Year: 2002
Pages: 181

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