Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Daniel Solis - Illustrated C# 2010 - 2010.pdf
Скачиваний:
16
Добавлен:
11.06.2015
Размер:
11.23 Mб
Скачать

CHAPTER 24 REFLECTION AND ATTRIBUTES

Predefined, Reserved Attributes

Before looking at how you can define your own attributes, this section describes two attributes predefined and reserved by .NET: the Obsolete and Conditional attributes.

The Obsolete Attribute

The Obsolete attribute allows you to mark a program construct as obsolete and to display a helpful warning message when the code is compiled. The following code shows an example of its use:

class Program

Apply attribute

 

{

 

 

 

 

 

[Obsolete("Use method SuperPrintOut")]

// Apply attribute to method

 

static void PrintOut(string str)

 

{

 

 

 

 

 

Console.WriteLine(str);

 

}

 

 

 

 

static void Main(string[] args)

 

{

 

 

 

 

 

PrintOut("Start of Main");

// Invoke obsolete method

}

 

 

 

}

 

 

 

 

 

Notice that method Main calls PrintOut even though it’s marked as obsolete. In spite of this, the code compiles and runs fine and produces the following output:

Start of Main

During compilation, though, the compiler produces the following CS0618 warning message to inform you that you’re using an obsolete construct:

'AttrObs.Program.PrintOut(string)' is obsolete: 'Use method SuperPrintOut'

Another overload of the Obsolete attribute takes a second parameter of type bool. This parameter specifies whether use of the target should be flagged as an error instead of just a warning. The following code specifies that it should be flagged as an error:

Flag as an error

[ Obsolete("Use method SuperPrintOut", true) ] // Apply attribute to method static void PrintOut(string str)

{ ...

647

CHAPTER 24 REFLECTION AND ATTRIBUTES

The Conditional Attribute

The Conditional attribute allows you to either include or exclude all the invocations of a particular method. To use the Conditional attribute, apply it to the method declaration, along with a compilation symbol as a parameter.

If the compilation symbol is defined, the compiler includes the code for all the invocations of the method, the way it would for any normal method.

If the compilation symbol is not defined, the compiler omits all the method invocations throughout the code.

The CIL code defining the method itself is always included in the assembly. It’s just the invocations that are either inserted or omitted.

For example, in the following code, the Conditional attribute is applied to the declaration of a method called TraceMessage. The attribute has a single parameter, which in this case is the string DoTrace.

When the compiler is compiling the code, it checks whether there is a compilation symbol named DoTrace defined.

If DoTrace is defined, the compiler includes all the calls to method TraceMessage, as usual.

If there is no DoTrace compilation symbol defined, it doesn’t output code for any of the calls to

TraceMessage.

Compilation symbol

[Conditional( "DoTrace" )]

static void TraceMessage(string str)

{

Console.WriteLine(str);

}

648

CHAPTER 24 REFLECTION AND ATTRIBUTES

Example of the Conditional Attribute

The following code shows a full example of using the Conditional attribute.

Method Main contains two calls to method TraceMessage.

The declaration for method TraceMessage is decorated with the Conditional attribute, which has the compilation symbol DoTrace as its parameter. So if DoTrace is defined, the compiler will include the code for all the calls to TraceMessage.

Since the first line of code defines a compilation symbol named DoTrace, the compiler will include the code for both calls to TraceMessage.

#define DoTrace using System;

using System.Diagnostics;

namespace AttributesConditional

{

class Program

{

[Conditional( "DoTrace" )]

static void TraceMessage(string str) { Console.WriteLine(str); }

static void Main( )

{

TraceMessage("Start of Main"); Console.WriteLine("Doing work in Main."); TraceMessage("End of Main");

}

}

}

This code produces the following output:

Start of Main

Doing work in Main.

End of Main

If you comment out the first line so that DoTrace is not defined, the compiler will not insert the code for the two calls to TraceMessage. This time, when you run the program, it produces the following output:

Doing work in Main.

649

CHAPTER 24 REFLECTION AND ATTRIBUTES

Predefined Attributes

The .NET Framework predefines a number of attributes that are understood and interpreted by the compiler and the CLR. Table 24-2 lists some of these. The table uses the short names, without the “Attribute” suffix. For example, the full name of CLSCompliant is CLSCompliantAttribute.

Table 24-2. Important Attributes Defined in .NET

Attribute

Meaning

CLSCompliant

Declares that the publicly exposed members should be checked by the compiler

 

for compliance with the CLS. Compliant assemblies can be used by any .NET-

 

compliant language.

Serializable

Declares that the construct can be serialized.

NonSerialized

Declares that the construct cannot be serialized.

Obsolete

Declares that the construct should not be used. The compiler also produces a

 

compile-time warning or error message, if the construct is used.

DLLImport

Declares that the implementation is unmanaged code.

WebMethod

Declares that the method should be exposed as part of an XML web service.

AttributeUsage

Declares what types of program constructs the attribute can be applied to. This

 

attribute is applied to attribute declarations.

 

 

650

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]