Attributes in C# are special classes used to add metadata to code elements.
This metadata can be read and used by the compiler, development tools, or the program itself at runtime through reflection.
Attributes derive from the base class System.Attribute
.
This metadata provides additional information about the elements of the program, such as classes, methods, properties, among others.
Syntax of attributes
An attribute is declared by placing the attribute name in square brackets ([ ]
) just before the declaration of the element it applies to. For example:
[Serializable]
public class Example { }
[Obsolete("This method is obsolete")]
public void OldMethod() { }
In these examples, Serializable
and Obsolete
are attributes that provide additional information about the class Example
and the method OldMethod
, respectively.
Using predefined attributes
There are many predefined attributes in .NET. Let’s look at some of them.
Serializable
Attribute
The Serializable
attribute is used to indicate that a class can be serialized, which means its instances can be converted into a format that can be stored or transmitted and then reconstructed.
[Serializable]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
In this example, the class Person
is marked as Serializable
, allowing its instances to be serialized.
Obsolete
Attribute
The Obsolete
attribute is used to mark code elements as obsolete, providing a warning or compilation error when they are used.
public class Example
{
[Obsolete("Use the NewMethod instead")]
public void OldMethod()
{
// Obsolete code
}
public void NewMethod()
{
// New code
}
}
Here, the method OldMethod
is marked with the Obsolete
attribute, indicating that NewMethod
should be used instead.
AttributeUsage
Attribute
The AttributeUsage
attribute is used to specify how and where a custom attribute can be applied.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class InfoAttribute : Attribute
{
public string Description { get; }
public InfoAttribute(string description)
{
Description = description;
}
}
In this example, a custom attribute InfoAttribute
is defined that can be applied to classes and methods, and allows multiple uses on the same element.
Defining and using custom attributes
In addition to using predefined attributes, it is also possible to define custom attributes according to the specific needs of the developer.
To define a custom attribute, a class that derives from System.Attribute
is created, and any necessary properties or fields are added.
Defining a custom attribute
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorAttribute : Attribute
{
public string Name { get; }
public string Date { get; }
public AuthorAttribute(string name, string date)
{
Name = name;
Date = date;
}
}
In this example, a custom attribute AuthorAttribute
is defined with two properties: Name
and Date
.
Using a custom attribute
[Author("Luis", "01/06/2023")]
public class Example
{
[Author("Luis", "01/06/2023")]
public void ExampleMethod()
{
// Method code
}
}
Here, the Author
attribute is applied to both the Example
class and the ExampleMethod
, providing information about the author and the date.
Reading attributes at runtime
Reflection in C# allows reading the attributes applied to code elements at runtime. This is done using the classes in the System.Reflection
namespace.
Type type = typeof(Example);
foreach (var attribute in type.GetCustomAttributes(typeof(AuthorAttribute), false))
{
AuthorAttribute author = (AuthorAttribute)attribute;
Console.WriteLine($"Class - Author: {author.Name}, Date: {author.Date}");
}
MethodInfo method = type.GetMethod("ExampleMethod");
foreach (var attribute in method.GetCustomAttributes(typeof(AuthorAttribute), false))
{
AuthorAttribute author = (AuthorAttribute)attribute;
Console.WriteLine($"Method - Author: {author.Name}, Date: {author.Date}");
}
In this example, the Author
attributes applied to the Example
class and the ExampleMethod
are read and displayed.