How to use attributes in C#

By FoxLearn 1/7/2025 2:16:26 AM   101
Attributes are a powerful feature in C# that allow you to attach metadata to your assemblies.

An attribute is an object that can be applied to various elements such as an assembly, class, method, delegate, enum, event, field, interface, property, or struct. Essentially, attributes allow you to inject extra data into your assemblies, which can then be queried later if needed. An attribute consists of a name, which corresponds to the attribute class, and optionally, a set of parameters.

Attributes can be used to enhance your application's business objects, such as for validation purposes. There are two types of attributes: intrinsic (built-in, part of the .NET framework) and custom (user-defined by inheriting from `System.Attribute`).

The Deprecated attribute can be used to mark a method as outdated indicating that it’s no longer recommended for use, perhaps due to better alternatives.

For example, how to apply the Deprecated attribute to a method declaration:

[Deprecated("This method is outdated...")]
public static void PerformOldTask()
{
    // Some legacy code
}

When this method is used in your code and you compile the program, a warning will appear in the output window of the Visual Studio IDE. Developers can choose to ignore this warning if they wish.

However, if you want to completely prevent its use, you can add a second parameter (which is optional) to the Deprecated attribute, like so:

[Deprecated("This method is outdated...", true)]
public static void PerformOldTask()
{
    // Some legacy code
}

By passing true as the second parameter, the code won’t compile at all, effectively stopping any use of the outdated method.

How to Custom attributes in C#?

In this section, we’ll explore how to create custom attributes. Custom attributes are user-defined classes that inherit from the System.Attribute class.

To create a custom attribute, simply define a new class that derives from System.Attribute:

using System;

public class MyCustomAttribute : Attribute
{
}

To control where and how your custom attribute can be applied, you can use the AttributeUsage class.

Let’s look at a more detailed version of the MyCustomAttribute class.

In this case, we’ll use a constructor to accept a string argument and store it in a private member variable, just for illustration:

[AttributeUsage(AttributeTargets.All)]
public class MyCustomAttribute : Attribute
{
    private string message;

    public MyCustomAttribute(string message)
    {
        this.Message = message;
    }

    public string Message
    {
        get { return this.message; }
        set { this.message = value; }
    }
}

You can also specify the exact targets where your custom attribute should be applied.

For example, you may want it to apply to classes, methods, fields, or properties. You can do this by using AttributeUsage with specific targets like this:

[AttributeUsage(AttributeTargets.Class | 
                AttributeTargets.Method | 
                AttributeTargets.Property, 
                AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{
    private string message;

    public MyCustomAttribute(string message)
    {
        this.Message = message;
    }

    public string Message
    {
        get { return this.message; }
        set { this.message = value; }
    }
}
 

This custom attribute can now be used on classes, methods, and properties, and multiple instances of the same attribute can be applied to the same target.

Now, to retrieve and display the attributes applied to an object, you can use reflection.

MemberInfo memberInfo = typeof(MyCustomAttribute);
object[] attributes = memberInfo.GetCustomAttributes(true);

for (int i = 0; i < attributes.Length; i++)
{
    Console.WriteLine(attributes[i]);
}

Now, let’s apply our custom attribute to a class and print out the content of the Message property:

[MyCustomAttribute("This is a custom message")]
public class SampleClass
{
}

To display the message from the MyCustomAttribute, you can use the following code:

MemberInfo memberInfo = typeof(SampleClass);
object[] attributes = memberInfo.GetCustomAttributes(true);

foreach (object attribute in attributes)
{
    MyCustomAttribute customAttribute = attribute as MyCustomAttribute;

    if (customAttribute != null)
    {
        Console.WriteLine("Message: {0}", customAttribute.Message);
    }
    else
    {
        Console.WriteLine();
    }
}

This code will print the Message property of the custom attribute, which in this case would output:

Message: This is a custom message