C# .NET. Attributes. The role of attributes

Attributes. The role of attributes. The need to use attributes. Custom attributes


Contents


Search other websites:




1. What are attributes? Why attributes are used in the programs?

When writing a program, a programmer uses a basic set of .NET types and also develops his own types (classes, interfaces, delegates, structures, enumerations). For all types from the .NET set, to which there is a reference in the program, and for the types that are actually developed, the compiler generates a corresponding description. This description is called metadata description of types.

From the point of view of the method of obtaining, metadata can be of two types:

  • the so-called standard metadata. This is metadata describing the .NET types used in the program (for example, SteamReader, FileStream, etc.) and the types actually developed (own classes, interfaces, structures, delegates, enumerations);
  • metadata obtained using so-called attributes. Attributes allow you to supplement a type (for example, a class) with additional characteristics of a declarative nature. Attributes are like annotations that are attached to program code and apply to a particular element of the program. Attributes define the behavior of the types to which they are attached.

From an implementation point of view, attributes are specially designed classes that derive from the abstract System.Attribute class.

Attributes can be applied to classes, interfaces, structures, methods, properties, assemblies, modules, and the like. If an attribute needs to be applied to a type, it is said to attach an attribute. If an attribute is attached to some element (class, method), then this attribute is not a member of this class, but it denotes additional information that is attached to the element.

There are a number of predefined built-in attributes available in the .NET namespaces that can be useful in your programs. In addition, the programmer has the ability to create his own (custom) attributes.

Figure 1 shows a snippet of an assembly with metadata that describes the attached attributes.

Supplementing an assembly with attribute metadata

Figure 1. Supplementing an assembly with attribute metadata

 

2. Creating and attaching a custom attribute. General form

Any custom attribute must inherit from the System.Attribute class. In the most general case, creating an attribute class looks like this:

class MyClassAttribute : Attribute
{
  // ...
}

Once the class of an attribute is defined, it can be attached to another class. The general form of attaching an attribute class is as follows

[MyClassAttribute(parameters)]
class MyClass
{
  // ...
}

here parameters – the parameters of the constructor of the attribute class.

If the constructor of the attribute class has no parameters, then the general form of attachment is as follows

[MyClassAttribute]
class MyClass
{
  // ...
}

 

3. Requirements and recommendations for declaring an attribute class

The only requirement when creating an attribute class is that the class must inherit from the System.Attribute class.

In addition, when using attributes in programs, you can define the following guidelines:

  • when declaring an attribute class, it is recommended that its name ends with the Attribute suffix. For example, MyClassVersionAttribute, MyClassCommentAttribute, etc.;
  • if an attribute is attached to a class, the Attribute suffix is optional. For example, if an attribute named MyClassCommentAttribute is attached to the MyClass class, then the name of this attribute class can be specified as MyClassComment by removing the Attribute suffix. However, if the suffix is not removed, there will be no error either.

 

4. Create a custom attribute class based on another attribute class. Attribute inheritance. General form

Attribute classes that are defined in a program can attach other attribute classes to themselves. In the simplest case, the general form of such an attachment is as follows:

[ AnotherClassAttribute1(parameters1),
  AnotherClassAttribute2(parameters2),
  ...
  AnotherClassAttribureN(parametersN)
]
class MyClassAttribute : Attribute
{
  // ...
}

here

  • AnotherClassAttribute1, AnotherClassAttribure2, AnotherClassAttribureN – attribute class names that are attached to the custom attribute class;
  • parameters1, parameters2, parametersN – parameters of constructors of attached attribute classes.

If only one attribute class is attached to an attribute class, then the general form looks more simplified.

[ AnotherClassAttribute(parameters) ]
class MyClassAttribute : Attribute
{
  // ...
}

 

5. An example of creating a custom attribute class. Getting information about an attribute class

The example demonstrates how to create a custom attribute class named MyClassCommentAttribute. The attribute class adds its own comment to the element. The attribute class MyClassCommentAttribute is attached to the MyClass class. The main() function demonstrates receiving information about the class of an attribute that is attached to the MyClass class.

using System;

namespace ConsoleApp18
{
  // Declaring an attribute containing a comment
  class MyClassCommentAttribute : Attribute
  {
    private string comment; // base field - comment

    // Constructor
    public MyClassCommentAttribute(string _comment)
    {
      comment = _comment;
    }
  }

  // The declaration of the class to which the attribute will be attached.
  // It is not necessary to provide the name of the attribute class.
  [MyClassCommentAttribute("This is a my class.")]
  class MyClass
  {
    // Internal fields and methods of the class
    // ...
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Receive attributes of MyClass class
      // 1. Receive data about MyClass type
      Type tp = typeof(MyClass);

      // 2. Get a list of the attributes that are attached to the class MyClass
      object[] attr = tp.GetCustomAttributes(false);

      // 3. Print the names of the attributes attached to MyClass
      Console.WriteLine("Attributes of class MyClass:");
      foreach (object o in attr)
      {
        Console.WriteLine(o.GetType().Name);
      }
      Console.ReadKey();
    }
  }
}

In the above code, on the line preceding the declaration of the class MyClass

...
[MyClassCommentAttribute("This is a my class.")]
...

the constructor of the class MyClassCommentAttribute is called, which in the class has the following declaration

...

class MyClassCommentAttribute : Attribute
{
  ...

  // Constructor
  public MyClassCommentAttribute(string _comment)
  {
    comment = _comment;
  }
}

The main() function gets information about the attributes attached to the MyClass class. In our case, this is one attribute MyClassCommentAttribute.

First, using the typeof() operator, we obtain an instance of type System.Type, which contains data about the type MyClass. Based on the obtained instance, using the GetCustomAttributes() method, an array of attribute classes is created, which has the object[] type. The names of the resulting attribute classes are displayed in the foreach loop.

 


Related topics