How to use custom attributes in C#
By FoxLearn 1/18/2025 3:00:29 AM 68
The Description
attribute stores a user-friendly description of a class or property, which can be read and displayed during runtime.
Unit testing frameworks identify test methods by looking for the TestMethod
attribute.
Web APIs often use attributes like HttpGet
and validation attributes such as Required
for model validation.
Create the Custom Attribute
To create a custom attribute, you need to inherit from the Attribute
class.
Here's an example of a custom attribute that stores the priority level of a task:
public class PriorityLevelAttribute : Attribute { public int Priority { get; } public PriorityLevelAttribute(int priority) { Priority = priority; } }
Attribute constructor parameters must be constant values, so you cannot pass variables or objects at runtime, only constants like numbers or enums.
Apply the Attribute
Next, you can apply this PriorityLevelAttribute
to an enum or class. Here, we apply it to an enum representing different task statuses:
public enum TaskStatus { [PriorityLevel(1)] HighPriority, [PriorityLevel(2)] MediumPriority, [PriorityLevel(3)] LowPriority }
In this example, we’ve set different priority levels for each status of a task.
Retrieve the Attribute Value at Runtime
To access the attribute value at runtime, you'll use reflection. Below is an example of how to extract the priority value from a TaskStatus
enum:
using System; using System.Reflection; using System.Linq; public static class TaskStatusExtensions { public static int GetPriority(this TaskStatus status) { Type taskStatusType = typeof(TaskStatus); string statusName = Enum.GetName(taskStatusType, status); MemberInfo[] memberInfo = taskStatusType.GetMember(statusName); if (memberInfo.Length != 1) { throw new ArgumentException($"TaskStatus of {status} should only have one memberInfo"); } IEnumerable<PriorityLevelAttribute> customAttributes = memberInfo[0].GetCustomAttributes<PriorityLevelAttribute>(); PriorityLevelAttribute priorityAttribute = customAttributes.FirstOrDefault(); if (priorityAttribute == null) { throw new InvalidOperationException($"TaskStatus of {status} has no PriorityLevelAttribute"); } return priorityAttribute.Priority; } }
Alternatively, you can use a more concise version by creating a generic method to retrieve any attribute:
public static class TaskStatusExtensions { private static T GetAttribute<T>(this TaskStatus status) where T : Attribute { return (status.GetType().GetMember(Enum.GetName(status.GetType(), status))[0] .GetCustomAttributes(typeof(T), inherit: false)[0] as T); } public static int GetPriority(this TaskStatus status) { return status.GetAttribute<PriorityLevelAttribute>().Priority; } }
Use the Attribute in Practice
Now you can use the custom attribute to determine the priority of a task and act accordingly.
Console.WriteLine("Task processing..."); Task[] tasks = LoadTasks(); // implementation not shown foreach (var task in tasks) { int priority = task.Status.GetPriority(); Console.WriteLine($"Task {task.Name} has priority level {priority}"); // Simulate processing based on priority if (priority == 1) { Console.WriteLine("Processing high-priority task first."); } else if (priority == 2) { Console.WriteLine("Processing medium-priority task next."); } else { Console.WriteLine("Processing low-priority task last."); } } Console.ReadKey();
In this example, we use the GetPriority
extension method to fetch the priority level of each task and determine its processing order based on the priority level defined with the PriorityLevelAttribute
.
- How to fix 'Failure sending mail' in C#
- How to Parse a Comma-Separated String from App.config in C#
- How to convert a dictionary to a list in C#
- How to retrieve the Executable Path in C#
- How to validate an IP address in C#
- How to retrieve the Downloads Directory Path in C#
- C# Tutorial
- Dictionary with multiple values per key in C#