X
Popular Searches

How Do Attributes Work in C#?

C#

In C#, Attributes are metadata tags assigned to code, including classes, types, methods, and fields. Using reflection, you can examine the tags to change behaviors in your program. We’ll show how to use them, and how to write your own.

What Are Attributes?

Simply put, attributes are metadata tags that hold some information. The syntax for them is the type name in square brackets above the code being tagged, like so:

[Attribute]
void Command() 
{

They can be attached to pretty much anything—classes, methods, fields, structs, types, etc. They can even be given parameters to provide input that can be accessed, though they are limited to basic types. You can set parameters by invoking the attribute like a method:

[Attribute("name", Test=false, Number=42)]

A common use case is marking fields for serialization. C# has a built-in [Serializable] tag, which supports serializing a class to bytes, and many third-party libraries will implement their own tags. For example, the C# driver for MongoDB includes many tags for serializing to Bson, and also a special tag that will interpret a string as the document ID.

C# built-in [Serializable] tag, which supports serializing a class to bytes.

Another common use case is tagging methods that are managed by a higher-level command handler. For example, a Discord Bot, registers a list of commands that get handled whenever someone sends a message. Rather than manually adding each command to the command handler every time you write a new one, you can instead tag the method with [Command("commandname")], and use the generic solution that will add them all automatically at runtime.

Tagging methods managed by a higher-level command handler.

You can read Microsoft’s documentation to learn more, but they’re quite simple.

How To Make Your Own Attributes

Of course, you can pretty easily create your own custom attributes to apply to your classes. All you have to do is create a class that extends from System.Attribute. You can also add an attribute on this class specifying how it should be used; for example, only applying to classes or structs.

Then, you can specify fields, and a constructor that will take the input params and populate the fields. When you use this attribute, it’s like calling new Attribute(params), except without the new keyword.

[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct)]  
public class AuthorAttribute : System.Attribute  
{  
    private string name;  
    public double version;  
  
    public AuthorAttribute(string name)  
    {  
        this.name = name;  
        version = 1.0;  
    }  
}

Then you’re free to use them to tag your code, provided that the attribute is referenced in the code being tagged.

Using contructor to tag your code.

To access attributes programmatically, you’ll need to use reflection. Reflection isn’t great for performance, but for the use cases of attributes, that usually doesn’t matter. You can use Attribute.GetCustomAttributes to return an Attribute[], passing in the type of the class:

System.Attribute.GetCustomAttributes(typeof(className));

If you want to access all instance of attributes across your assembly, you can use Assembly.GetExecutingAssembly().GetTypes() to fetch a list of executing types and then check all the custom attributes of that type to see if it contains the search parameter, optionally filtering that list based on the type of class the attribute is attached to.

var plugins = Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => t.IsClass 
            && t.BaseType == typeof(BasePlugin) 
            && Attribute.GetCustomAttributes(t).Any((atr) => atr.GetType() == typeof(MyCustomAttribute)))
    .ToList();

Use Assembly.GetExecutingAssembly().GetTypes() to fetch list of executing types, then check all custom attributes to see if it contains search parameter.

To access attribute parameters, you simply access them directly from the Attribute class, like any other public properties.

Anthony Heddings Anthony Heddings
Anthony Heddings is the resident cloud engineer for LifeSavvy Media, a technical writer, programmer, and an expert at Amazon's AWS platform. He's written hundreds of articles for How-To Geek and CloudSavvy IT that have been read millions of times. Read Full Bio »

The above article may contain affiliate links, which help support CloudSavvy IT.