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

CHAPTER 24 REFLECTION AND ATTRIBUTES

Custom Attributes

You’ve probably noticed that the syntax for applying an attribute is very different from anything you’ve seen so far. From that, you might get the impression that attributes are an entirely different type of construct. They’re not—they’re just a special kind of class.

Some important points about attribute classes are the following:

User-defined attribute classes are called custom attributes.

All attribute classes are derived from class System.Attribute.

Declaring a Custom Attribute

Declaring an attribute class is, for the most part, the same as declaring any other class. There are, however, several things to be aware of:

To declare a custom attribute, do the following:

Declare a class derived from System.Attribute.

Give it a name ending with the suffix Attribute.

For security, it’s generally suggested that you declare your attribute classes as sealed.

For example, the following code shows the beginning of the declaration of attribute

MyAttributeAttribute:

Attribute name

public sealed class MyAttributeAttribute : System.Attribute

{

 

 

...

 

Suffix

 

Base class

Since an attribute holds information about the target, the public members of an attribute class generally consist only of the following:

Fields

Properties

Constructors

654

CHAPTER 24 REFLECTION AND ATTRIBUTES

Using Attribute Constructors

Attributes, like other classes, have constructors. Every attribute must have at least one public constructor.

As with other classes, if you don’t declare a constructor, the compiler will produce an implicit, public, parameterless constructor for you.

Attribute constructors, like other constructors, can be overloaded.

When declaring the constructor, you must use the full class name, including the suffix. You can use the shortened name only when applying an attribute.

For example, with the following constructor, the compiler would produce an error message if the name did not include the suffix:

Suffix

public MyAttributeAttribute(string desc, string ver)

{

Description = desc; VersionNumber = ver;

}

Specifying the Constructor

When you apply an attribute to a target, you are specifying which constructor should be used to create the instance of the attribute. The parameters listed in the attribute application are the actual parameters for the constructor.

For example, in the following code, MyAttribute is applied to a field and to a method. For the field, the declaration specifies a constructor with a single string parameter. For the method, it specifies a constructor with two string parameters.

[MyAttribute("Holds a

value")]

//

Constructor

with

one

string

public int MyField;

 

 

 

 

 

 

[MyAttribute("Version

1.3", "Sal Martin")]

//

Constructor

with

two

strings

public void MyMethod()

 

 

 

 

 

 

{ ...

 

 

 

 

 

 

655

CHAPTER 24 REFLECTION AND ATTRIBUTES

Other important points about attribute constructors are the following:

When applying an attribute, the actual parameters for the constructor must be constant expressions whose values can be determined at compile time.

If you apply an attribute constructor with no parameters, you can leave off the parentheses. For example, both classes in the following code use the parameterless constructor for the attribute MyAttr. The meanings of the two forms are the same.

[MyAttr]

class SomeClass ...

[MyAttr()]

class OtherClass ...

Using the Constructor

You cannot call the constructor explicitly. An instance of an attribute is created, and a constructor called, only when an attribute consumer accesses the attribute. This is very different from other class instances, which are created at the position where you use an object-creation expression. Applying an attribute is a declarative statement that does not determine when an object of the attribute class should be constructed.

Figure 24-4 compares the use of a constructor for a regular class and the use of a constructor with attributes.

The imperative statement says, in effect, “Create a new class object here.”

The declarative statement says, “This attribute is associated with this target, and in case the attribute needs to be constructed, use this constructor.”

Figure 24-4. Comparing the use of constructors

656

CHAPTER 24 REFLECTION AND ATTRIBUTES

Positional and Named Parameters in Constructors

Like the methods and constructors of regular classes, the attribute constructors can also use positional and named parameters.

The following code shows the application of an attribute using a positional parameter and two named parameters:

Positional parameter

 

Named parameter

 

Named parameter

 

 

[MyAttribute("An excellent class", Reviewer="Amy McArthur", Ver="0.7.15.33")]

 

 

Equals sign

Equals sign

The following code shows the declaration of the attribute class, as well as its application on class MyClass. Notice that the constructor declaration lists only a single formal parameter. And yet, by using named parameters, you can give the constructor three actual parameters. The two named parameters set the values of fields Ver and Reviewer.

public sealed class MyAttributeAttribute : System.Attribute

{

public string Description; public string Ver;

public string Reviewer;

 

public MyAttributeAttribute(string desc) // Single formal parameters

 

{ Description = desc; }

}

 

Three actual parameters

 

 

 

[MyAttribute("An excellent class", Reviewer="Amy McArthur", Ver="7.15.33")] class MyClass

{... }

Note If the constructor requires any positional parameters, they must be placed before any named parameters.

657

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