Custom Attributes and Reflection

Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

Custom Attributes and Reflection

11 October 2022 18:48

Step1: Create custom attribute


Step2: Specify the attribute usage
Step3: Apply the attribute
Step4: View the attribute
Step5: Retrieve and display the attribute using 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)]

public class FieldNameAttribute: Attribute


{
private string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
}

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

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple=false,


Inherited=false)]

Specifying Attribute Parameters


When the compiler encounters a statement, it examines the parameters passed into the attribute —
which is a string — and looks for a constructor for the attribute that takes exactly those parameters:
[FieldName("SocialSecurityNumber")] [FieldName("SocialSecurityNumber","12345")]
public string SocialSecurityNumber public string SocialSecurityNumber
{ {
} }
If the compiler finds an appropriate constructor, it emits the specified metadata to the assembly.
If the compiler does not find an appropriate constructor, a compilation error occurs.

[AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)]


public class FieldNameAttribute: Attribute
{
private string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
}

Specifying Optional Attribute Parameters

[FieldName("SocialSecurityNumber", Comment="This is the primary key field")]


public string SocialSecurityNumber
{

–Optional parameters can be added to an attribute


–It works through public properties or fields in the attribute class
–the compiler recognizes the < ParameterName > = < ParameterValue > syntax of the second parameter
and does not attempt to match this parameter to the constructor

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;
}

private string comment;


public string Comment
{
get
{
return comment;
}
set
{
comment = value;
}
}
// etc
}

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

You might also like