Create Custom C# Attributes – A Starters Guide

by Kenji Elzerman
Introduction To Building Your Own C# Attributes - A Starters Guide - Kens Learning Curve

Those of us who have worked with C# for a while might have seen attributes: keywords, or classes, located on top of a class, method, property, or parameters surrounded by square brackets. C# Attributes are a way to add and gather information about various elements of our code. Although there are plenty in the frameworks, it’s also possible to create custom C# attributes.

Goals

In this article, we are going to explore attributes. Not only existing attributes but also how we can create custom C# attributes of our own.

After this article you

  • Understand basic attributes and data annotations
  • Create your own attribute and use it in a web API

C# Attributes

There are many attributes that we use a lot. For example, the Required attribute is usually located on top of a property in a class. This attribute indicates that the property is required and you will get an exception when empty. If you look at the class below you will see that the property Title is required.

public class Movie
{
    [Required]
    public string Title { get; set; }
    public string Plot { get; set; }
    public DateTime ReleaseDate { get; set; }
    public bool Seen { get; set; }
    public int Rating { get; set; }
}

If I want to use this class as post data in an API and don’t send a value for the title, the API will throw an exception that the title can’t be empty.

DataAnnotations

The Required attribute is located in the namespace System.ComponentModel.DataAnnotations, which is a popular namespace for everything being used for handling validation on model classes and properties. In addition, attributes, located in the DataAnnotations, are MaxLength, EmailAddress, Range, DataType, and much more. These are also used a lot when working with Entity Framework.

It is possible to stack attributes for one class or property, as shown below.

public class Movie
{
    public int Id { get; set; }
    [Required]
    [MaxLength(50)]
    public string Title { get; set; }
    public string Plot { get; set; }
    public DateTime ReleaseDate { get; set; }
    public bool Seen { get; set; }
    [Range(0, 5)]
    [Required]
    public int Rating { get; set; }
}

DataAnnotations do a lot of validation for you so you don’t have to think of it too much or create special methods to check if something satisfies specific criteria.

Create Custom C# Attributes

When programming and using a framework, like .NET, it never has what you want. Luckily for us, the whole .NET framework is built to give you a set of tools but feel free to expand or add your own. You can create custom C# attributes if you feel the need.

In this example, I am going to create a console application and show the information of movies, with each property of a movie in a different color. An attribute in the Movie class on each property defines that color.

The Attribute

Let’s create the attribute first. The idea is to decorate the properties of the future Movie class with an attribute where I can state the color.

Creating an attribute is as simple as creating a class. It is a class with an inheritance to Attribute. The only thing you need to keep in mind is the naming convention, which states that the name of the attribute class ends with “Attribute”.

Creating The Class

A custom attribute also has attributes (the irony). You need to define how the attribute can be used, by using the attribute AttributeUsage. Furthermore, you can define the target – which can be a class, property, etc – and you can use the attribute on the same target multiple times (true/false).

Let’s start by adding a class into our console application and calling it ColorAttribute. I will also add the inheritance and the AttributeUsage.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ColorAttribute : Attribute
{
   
}

I have configured the attribute in a way it can only be used on properties and it can only be used once on a property.

Setting And Retrieving Color

We can add parameters to set on the attribute by adding a constructor to the attribute. In this case, we want to set the color so I add a ConsoleColor data type to the parameter list of the constructor. I set the default color on ConsoleColor.White and also add a public ConsoleColor so I can access it from another class.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ColorAttribute : Attribute
{
    public ColorAttribute(ConsoleColor color = ConsoleColor.White)
    {
        Color = color;
    }

    public ConsoleColor Color { get; }
}

This looks like a regular class with a constructor and a read-only property… It is. However, the naming convention and the inheritance with Attribute make it an attribute. Time to put it to use.

Movie Class

I want to use the attribute in the Movie class, which I have been using a lot in my articles. So here is the basic setup for the Movie class:

public class Movie
{
    public string Title { get; set; }
    public string Description { get; set; }
    public int Rating { get; set; }
}

Now I want to add colors to each property. Time to get out the ColorAttribute:

public class Movie
{
    [Color(ConsoleColor.Red)]
    public string Title { get; set; }
    [Color(ConsoleColor.Blue)]
    public string Description { get; set; }
    [Color(ConsoleColor.Green)]
    public int Rating { get; set; }
}

Do you notice that the Attribute of ColorAttribute is not there? That is because of the naming convention. C# will remove it to keep the code clean and easy to read. It is part of the C# language design.

Showing Some Movies

Let’s move to the Program.cs. I will not explain much about the following code since it must seem pretty straightforward.

var movies = new List<Movie>
{
    new Movie{ Description = "Green fellow", Title = "Shrek", Rating = 5},
    new Movie{ Description = "Worst movie with Ryan Reynolds", Title = "Green Latern", Rating = 1},
    new Movie{ Description = "To hard to follow and I still don't get", Title = "Inception", Rating = 5},
    new Movie{ Description = "A movie that would even make Dwayne Johnson cry", Title = "Titanic", Rating = 5}
};

foreach (var item in movies)
{
    Console.WriteLine(item.Title);
    Console.WriteLine("A rating of " + item.Rating);
    Console.WriteLine(item.Description);
    Console.WriteLine(string.Empty);
}

If you run this, you will see this:

White result - Create Custom C# Attributes - Kens Learning Curve

We now need to extract the information from the attribute and use it.

Getting Attribute Information

We need one method to read the attributes of the property we are reading and get the color. We then send back that color, use it, and move to the next property.

ConsoleColor GetPropertyColor(string propertyName)
{
    PropertyInfo propertyInfo = typeof(Movie).GetProperty(propertyName);
    ColorAttribute colorAttribute = (ColorAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(ColorAttribute));

    if (colorAttribute != null)
        return colorAttribute.Color;

    return defaultColor;
}

This method gets the name of the property and looks it up in the Movie class using reflection. When the property is found C# can read the attribute ColorAttribute and extract the information. If the attribute is found, the color is sent back. Otherwise, the default color, which will be set before showing the movies, will be returned.

The complete Program.cs (minus the usings) is now this:

ConsoleColor defaultColor = Console.ForegroundColor;

var movies = new List<Movie>
{
    new Movie{ Description = "Green fellow", Title = "Shrek", Rating = 5},
    new Movie{ Description = "Worst movie with Ryan Reynolds", Title = "Green Latern", Rating = 1},
    new Movie{ Description = "To hard to follow and I still don't get", Title = "Inception", Rating = 5},
    new Movie{ Description = "A movie that would even make Dwayne Johnson cry", Title = "Titanic", Rating = 5}
};

foreach (var item in movies)
{
    Console.ForegroundColor = GetPropertyColor(nameof(item.Title));
    Console.WriteLine(item.Title);

    Console.ForegroundColor = GetPropertyColor(nameof(item.Rating));
    Console.WriteLine("A rating of " + item.Rating);

    Console.ForegroundColor = GetPropertyColor(nameof(item.Description));
    Console.WriteLine(item.Description);

    Console.ForegroundColor = defaultColor;
    Console.WriteLine(string.Empty);
}

ConsoleColor GetPropertyColor(string propertyName)
{
    PropertyInfo propertyInfo = typeof(Movie).GetProperty(propertyName);
    ColorAttribute colorAttribute = (ColorAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(ColorAttribute));

    if (colorAttribute != null)
        return colorAttribute.Color;

    return defaultColor;
}

In this code, I get the color from the property’s attribute and set the foreground color.

This is the result:

Colored result - Create Custom C# Attributes - Kens Learning Curve

A Little Bit Extra

The attribute is pretty simple. Let’s add something extra: A random color. By adding an empty constructor to the attribute class we can determine if the C# code should generate a color or use the color we have set.

The property Color will then check if it needs to generate a random color or return the set color.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ColorAttribute : Attribute
{
    private bool randomColor;
    private ConsoleColor color;

    public ColorAttribute()
    {
        randomColor = true;
    }

    public ColorAttribute(ConsoleColor color = ConsoleColor.White)
    {
        Color = color;
    }

    public ConsoleColor Color
    {
        get
        {
            if (randomColor)
            {
                ConsoleColor[] consoleColors = (ConsoleColor[])Enum.GetValues(typeof(ConsoleColor));
                Random random = new();
                return consoleColors[random.Next(consoleColors.Length)];
            }
            else
                return color;
        }
        private set
        {
            color = value;
        }
    }
}

You need to change the Movie properties a bit, but it’s just one time.

public class Movie
{
    [Color()]
    public string Title { get; set; }
    [Color(ConsoleColor.Blue)]
    public string Description { get; set; }
    [Color(ConsoleColor.Green)]
    public int Rating { get; set; }
}

The title should now generate a random color. The description and rating have a fixed color. The output of the console application now looks like this:

Random color result - Create Custom C# Attributes - Kens Learning Curve

Conclusion On Create Custom C# Attributes

Yes, it’s that simple. All you need to do is create a class with a name that ends with ‘Attribute’, some code in that class, use the attribute somewhere, and get the information when using it. This is the basics of how to create custom C# attributes There are tons of examples to think of that could be a great attribute, but I would start with something simple.

But before you start building a super cool attribute, always make sure it doesn’t exist or maybe you can reuse an existing one by inheriting it. That’s what the whole .NET framework is built for.

Table Of Contents
Kens Learning Curve