Custom Attributes and Reflection
Custom Attributes and Reflection
Custom Attributes and Reflection
Coding:
Custom attributes are mechanisms that enable you to associate custom metadata with program
elements.
This metadata is created at compile time and embedded in an assembly.
Reflection is a generic term that describes the capability to inspect and manipulate program elements at
runtime.
Predefined attributes defined by Microsoft as part of the .NET Framework class library.
The .NET Framework also enables you to define your own attributes.
Obviously, these attributes won’t have any effect on the compilation process because the compiler has
no intrinsic awareness of them.
However, these attributes will be emitted as metadata in the compiled assembly when they are applied
to program elements.
By itself, this metadata might be useful for documentation purposes, but what makes attributes really
powerful is that by using reflection, your code can read this metadata and use it to make decisions at
runtime.
This means that the custom attributes that you define can directly affect how your code runs.
To understand how to write your own custom attributes, it is useful to know what the compiler does
when it encounters an element in your code that has a custom attribute applied to it.
[FieldName("SocialSecurityNumber")]
public string SocialSecurityNumber
{
get {
// etc.
[FieldNameAttribute("SocialSecurityNumber")]
public string SocialSecurityNumber
{
get {
// etc.
The compiler also expects that this class contains information governing the use of the attribute.
In particular, the attribute class needs to specify the following:
➤ The types of program elements to which the attribute can be applied (classes, structs, properties,
methods, and so on)
➤ Whether it is legal for the attribute to be applied more than once to the same program element
C Sharp Page 1
➤ Whether it is legal for the attribute to be applied more than once to the same program element
➤ Whether the attribute, when applied to a class or interface, is inherited by derived classes and
interfaces
➤ The mandatory and optional parameters the attribute takes
If the compiler cannot find a corresponding attribute class, or if it finds one but the way that you have
used that attribute does not match the information in the attribute class, the compiler will raise a
compilation error.
Continuing with the example, assume that you have defined the FieldName attribute like this:
[AttributeUsage(AttributeTargets.Property,
AllowMultiple=false,
Inherited=false)]
For example, if the attribute class indicates that the attribute can be applied only to property but you
have applied it to a struct or class definition, a compilation error will occur.
The primary steps to properly design custom attribute classes are as follows:
1.Applying the AttributeUsage Attribute
2.Declaring the attribute class
3.Declaring constructors
4.Declaring properties
AttributeUsage Attribute:
–Purpose is to identify the types of program elements to which your custom attribute can be applied
–3 parameters: AttributeTargets, AllowMultiple, Inherited
–This information is given by the first parameter of the AttributeUsage attribute: an enumerated type,
AttributeTargets
•The members of the AttributeTargets enumeration are:
All
Assembly
Class
Constructor
Delegate
Enum
Event
Field
Struct
GenericParameter (from .NET 2.0 on only)
Interface
Method
Module
Parameter
Property
ReturnValue
When indicating the valid target elements of a custom attribute, you can combine these values using the
bitwise OR operator
[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Struct) ]
public class FieldNameAttribute: Attribute{
}
[FieldName("SocialSecurityNumberClass")]
public Struct SocialSecurityNumberStruct
{
}
[FieldName("SocialSecurityNumberClass")]
public class SocialSecurityNumberClass
{
}
C Sharp Page 2
[FieldName("SocialSecurityNumberClass")]
public class SocialSecurityNumberClass
{
}
use AttributeTargets.All to indicate that your attribute can be applied to all types of program elements
[FieldName("SocialSecurityNumber")]
public string SocialSecurityNumber
{
}
[FieldName("SocialSecurityNumberClass")]
public class SocialSecurityNumberClass
{
}
AllowMultiple, with which you can make a custom attribute single-use or multiuse.
[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Struct,
AllowMultiple=false)]
[FieldName("NationalInsuranceNumber")]
public string SocialSecurityNumber
{
}
[FieldName("SocialSecurityNumber")]
[FieldName("NationalInsuranceNumber")]
public string SocialSecurityNumber
{
}
•If the Inherited parameter is set to true , an attribute applied to a class or interface will also
automatically be applied to all derived classes or interfaces
•If the attribute is applied to a method or property, it will automatically apply to any overrides of that
method or property
C Sharp Page 3
and does not attempt to match this parameter to the constructor
[AttributeUsage(AttributeTargets.Property,
AllowMultiple=false,
Inherited=false)]
public class FieldNameAttribute: Attribute
{
private string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
C Sharp Page 4
C Sharp Page 5
C Sharp Page 6
C Sharp Page 7
Getting custom attribute from methods:
C Sharp Page 8
C Sharp Page 9
C Sharp Page 10