15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

336 ❘ ChaPTer 14 reflectiOn<br />

code; in this case the attribute can be placed anywhere in your source code, but needs to be prefixed with<br />

the Assembly or Module keyword:<br />

[assembly:SomeAssemblyAttribute(Parameters)]<br />

[module:SomeAssemblyAttribute(Parameters)]<br />

When indicating the valid target elements of a custom attribute, you can combine these values using the<br />

bitwise OR operator. For example, if you want to indicate that your FieldName attribute can be applied to<br />

both properties <strong>and</strong> fields, you would write:<br />

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field,<br />

AllowMultiple=false,<br />

Inherited=false)]<br />

public class FieldNameAttribute: Attribute<br />

You can also use AttributeTargets.All to indicate that your attribute can be applied to all types of<br />

program elements. The AttributeUsage attribute also contains two other parameters, AllowMultiple<br />

<strong>and</strong> Inherited. These are specified using the syntax of =, instead of<br />

simply giving the values for these parameters. These parameters are optional — you can omit them if<br />

you want.<br />

The AllowMultiple parameter indicates whether an attribute can be applied more than once to the<br />

same item. The fact that it is set to false here indicates that the compiler should raise an error if it sees<br />

something like this:<br />

[FieldName("SocialSecurityNumber")]<br />

[FieldName("NationalInsuranceNumber")]<br />

public string SocialSecurityNumber<br />

{<br />

// etc.<br />

If the Inherited parameter is set to true, an attribute applied to a class or interface will also automatically<br />

be applied to all derived classes or interfaces. If the attribute is applied to a method or property, it will<br />

automatically apply to any overrides of that method or property, <strong>and</strong> so on.<br />

specifying attribute Parameters<br />

This section examines how you can specify the parameters that your custom attribute takes. The way it<br />

works is that when the compiler encounters a statement such as the following,<br />

[FieldName("SocialSecurityNumber")]<br />

public string SocialSecurityNumber<br />

{<br />

// etc.<br />

the compiler examines the parameters passed into the attribute — which is a string — <strong>and</strong> looks for<br />

a constructor for the attribute that takes exactly those parameters. If the compiler finds an appropriate<br />

constructor, the compiler will emit the specified metadata to the assembly. If the compiler does not find an<br />

appropriate constructor, a compilation error occurs. As discussed later in this chapter, reflection involves<br />

reading metadata (attributes) from assemblies <strong>and</strong> instantiating the attribute classes they represent.<br />

Because of this, the compiler must ensure that an appropriate constructor exists that will allow the runtime<br />

instantiation of the specified attribute.<br />

In the example, you have supplied just one constructor for FieldNameAttribute, <strong>and</strong> this constructor takes<br />

one string parameter. Therefore, when applying the FieldName attribute to a property, you must supply one<br />

string as a parameter, as was done in the preceding sample code.<br />

If you want to allow a choice of what types of parameters should be supplied with an attribute, you can<br />

provide different constructor overloads, although normal practice is to supply just one constructor <strong>and</strong> use<br />

properties to define any other optional parameters, as explained next.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!