Attributes in C Tutorial LEARNOVITA

Attributes in C# Tutorial | Learn to work with attributes in C#

Last updated on 12th Aug 2022, Blog, Tutorials

About author

Jagan Mohan (Senior C# Developer )

Jagan Mohan is a Senior Senior C# Developer and has extensive knowledge in the following areas of WPF, XML, REST, Agile, V model, C#, SQL server, Web API, and ASP.NET.

(5.0) | 19482 Ratings 2347

Attributes in C#

Methods, assemblies, structures, enumerators, types, properties, etc. can all benefit from using metadata in the form of attributes. Declarative tags, made by adding square brackets before the necessary element, are used to define the characteristics.

Attributes Uses

Some of the major uses of attributes are given as follows:

    1. 1.Attributes can be used to define the characteristics of COM components such as methods, classes, interfaces, and so on.
    2. 2.Web services allow for the annotation of methods via the WebMethod property.
    3. 3.The DLLImport Attribute class allows you to make calls to unmanaged code via attributes.
    4. 4.Version, trademark, title, description, etc. are only some of the features that can be used to classify the assembly..
    5. 5.Attributes may be used to define the correspondence between class members and XML codes. To serialise XML, use this.
    6. 6.Attributes can be utilised to define the various features of security management.
    7. 7.Attributes identify the class members that must be serialised for persistence

Attribute Syntax:

The following is the syntax for specifying attributes:

  • [ attributeName (parameter_1, parameter_2…..parameter_n) ]

Elements

In the above format, the attribute class is denoted by attributeName, which may be followed by zero or more parameters. Data is stated in square brackets.

Predefined Attributes

The three pre-defined attributes:

  • AttributeUsage
  • Conditional
  • Obsolete

AttributeUsage:

This is the pre-defined characteristic. What kinds of things can be done with a custom attribute class are defined in AttributeUsage. It outlines the categories of things that can be modified with the attribute.

This attribute can be specified using the following syntax:

  • AttributeUsage
  • validon,
  • AllowMultiple = allowmultiple,
  • Inherited = inherited
  • )]

Where,the valid on argument identifies which language components support the attribute. It’s a sum total of the items in an enumerator called AttributeTargets. AttributeTargets is the default option. All allowMultiple is a Boolean property of this attribute, and it is set by the (optional) input allowmultiple. In this case, we might say that the attribute has many purposes. Since false is the default (single-use).The Inherited property of this attribute accepts a Boolean value, and that value is specified by the argument inherited (optional). If so, the attribute will be passed down to child classes. True is not the default setting (not inherited).For example,

  • [AttributeUsage(
  • AttributeTargets.Class |
  • AttributeTargets.Constructor |
  • AttributeTargets.Field |
  • AttributeTargets.Method |
  • AttributeTargets.Property,
  • AllowMultiple = true)]

Conditional:

This built-in characteristic designates a method as conditional on the value of a preprocessing identifier.Method invocations are conditionally compiled according to the value supplied, such as Debug or Trace. When debugging, it shows you things like what the values of your variables are.

Syntax for specifying this attribute is as follows:

  • [Conditional(
  • conditionalSymbol
  • )]

For example,

  • [Conditional(“DEBUG”)]
  • #define DEBUG
  • using System;
  • using System.Diagnostics;
  • public class Myclass {
  • [Conditional(“DEBUG”)]
  • public static void Message(string msg) {
  • Console.WriteLine(msg);
  • }
  • }
  • class Test {
  • static void function1() {
  • Myclass.Message(“In Function 1.”);
  • function2();
  • }
  • static void function2() {
  • Myclass.Message(“In Function 2.”);
  • }
  • public static void Main() {
  • Myclass.Message(“In Main function.”);
  • function1();
  • Console.ReadKey();
  • }
  • }
  • When the above code is compiled and executed, it produces the following result
  • In Main function
  • In Function 1
  • In Function 2

Obsolete:

Avoid use this program entity, which has been flagged with this predefined attribute. It lets you tell the compiler to ignore a specified piece of code at compile time. When a new method replaces an older one in a class, for instance, the older one can be marked as outdated by showing a warning that it should be avoided in favour of the newer one.

Syntax for specifying this attribute is as follows:

  • [Obsolete (
  • message
  • )]
  • [Obsolete (
  • message,
  • iserror
  • )]

Where,the parameter message, which is a string, explains why the product is no longer relevant and suggests alternatives. A Boolean value, like the one used for the is error parameter. The compiler should consider the use of the item to be incorrect if its value is true. The default is false (compiler generates a warning).

The following program demonstrates this:

  • using System;
  • public class MyClass {
  • [Obsolete(“Don’t use OldMethod, use NewMethod instead”, true)]
  • static void OldMethod() {
  • Console.WriteLine(“It is the old method”);
  • }
  • static void NewMethod() {
  • Console.WriteLine(“It is the new method”);
  • }
  • public static void Main() {
  • OldMethod();
  • }
  • }

Creating Custom Attributes

The.Net Framework enables developers to build their own attributes, which may then be utilised to save and retrieve declarative data at runtime.Depending on the design constraints and application necessity, this data can be linked to any target element.

There are four phases involved in creating and using custom attributes.

  • Accessing Attributes Via Reflection
  • Declaring a Custom Attribute
  • Creating the Custom Attribute
  • Applying the Custom Attribute to a Target Element in the Code

Declaring a Custom Attribute

A new custom attribute should is derived from the System.Attribute class. For example,

  • //a custom attribute BugFix to be assigned to a class and its members
  • [AttributeUsage(
  • AttributeTargets.Class |
  • AttributeTargets.Constructor |
  • AttributeTargets.Field |
  • AttributeTargets.Method |
  • AttributeTargets.Property,
  • AllowMultiple = true)]
  • public class DeBugInfo : System.Attribute

A new, user-defined attribute called “DeBugInfo” has been introduced in the accompanying code.

Constructing the Custom Attribute

Let’s make a special attribute called DeBugInfo that can be used to save data discovered during the debugging of any given software. Keep the following in its memory:

A string message to store the developer’s comments,the bug’s identification number; the developer’s name; the date of the most recent code review.These first three pieces of data are stored in the class’s private properties, while the message is kept in the class’s public property. This means that the DeBugInfo class’s positional parameters are the bug number, developer’s name, and review date, and its optional or named parameter is the message.There needs to be at least one function Object() for every attribute. The function Object() is where you should supply the coordinates. The DeBugInfo class is displayed in the following code.

  • //a custom attribute BugFix to be assigned to a class and its members
  • [AttributeUsage(
  • AttributeTargets.Class |
  • AttributeTargets.Constructor |
  • AttributeTargets.Field |
  • AttributeTargets.Method |
  • AttributeTargets.Property,
  • AllowMultiple = true)]
  • public class DeBugInfo : System.Attribute {
  • private int bugNo;
  • private string developer;
  • private string lastReview;
  • public string message;
  • public DeBugInfo(int bg, string dev, string d) {
  • this.bugNo = bg;
  • this.developer = dev;
  • this.lastReview = d;
  • }
  • public int BugNo {
  • get {
  • return bugNo;
  • }
  • }
  • public string Developer {
  • get {
  • return developer;
  • }
  • }
  • public string LastReview {
  • get {
  • return lastReview;
  • }
  • }
  • public string Message {
  • get {
  • return message;
  • }
  • set {
  • message = value;
  • }
  • }
  • }

Attribute Programming:

Attributes in C# are specialised classes that extend the Attribute superclass. All classes that extend Attribute can be applied to other objects as labels. Example: “ObsoleteAttribute” is an attribute that has since become obsolete. As a warning that the code is no longer supported, this is displayed. For example, square brackets allow you to apply this property to a class.

  • C#Copy
  • [Obsolete]
  • public class MyClass
  • {
  • }

It’s important to remember that while the class is named ObsoleteAttribute, only the keyword [Obsolete] is really used in the actual code. C# adheres to this standard. If you want, you may refer to this attribute by its longer form, [ObsoleteAttribute]. When declaring a class to be deprecated, it’s helpful to explain why and suggest alternatives. The Obsolete property accepts a string as an input for this purpose.

  • C#Copy
  • [Obsolete(“ThisClass is obsolete. Use ThisClass2 instead.”)]
  • public class ThisClass
  • {
  • }

Multiple “targets” can benefit from attributes’ application. However, they are not limited to their application on classes as shown above; see also:

  • Assembly
  • Class
  • Constructor
  • Delegate
  • Enum
  • Event
  • Field
  • GenericParameter
  • Interface
  • Method
  • Module
  • Parameter
  • Property
  • ReturnValue
  • Struct

By default, C# allows you to apply an attribute class to any of the supported targets when you construct the class.

Advantages of using Attributes:

    1. 1.The compiler can use an attribute if it can access it. This Machine, the System. Some standard attributes that are designated just for the compiler are not saved in the assembly, and the ObsoleteAttribute attribute we just mentioned is an excellent illustration of how a compiler uses an attribute. To give just one example, the SerializationAttribute attribute does not explicitly label a type but rather informs the compiler that the type in question is serializable. Pseudo-attributes are attributes that are set by the compiler and then used by the CLR when the code is being executed.
    2. 2.At runtime, the CLR can use an attribute as input. You can use the System in the.NET Framework, for instance. Attribute for ThreadStatic. When applied to a static field, this attribute ensures that the CLR creates a single copy of the field for each thread.
    3. 3.A debugger can use an attribute to track down problems as code is running. System.Diagnostics was therefore created. As an example, the status of an object can be displayed differently depending on the debugger settings and the user’s preferences using the DebuggerDisplayAttribute feature.
    4. 4.Having a ComVisibleAttribute is a plus. This attribute tells the tlbexp.exe tool to treat the class like a COM object and create a file that can be used to access the class as though it were a COM object.
    5. 5.By employing the reflection mechanism, your own code can access information about an attribute as it is being executed. Validating the values of fields in your classes, for instance, might be an engaging use of such properties. A field of this kind needs to conform to certain specifications. A different field used as a reference cannot be empty. The maximum allowed length for a string field is 100 characters. The reflection method makes it simple to verify the values of all indicated fields in code. A code-based example of consuming characteristics will be provided shortly.
    6. 6.A user who examines an assembly using ildasm.exe or Reflector can make use of an attribute. Therefore, it is possible to conceive of an attribute that links a character string to a component of your code. Because this text is part of the assembly, you may see the annotations without having the source code in front of you.

Are you looking training with Right Jobs?

Contact Us

Popular Courses