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 via reflection.
Attributes derive from the base class System.Attribute
.
This metadata provides additional information about program elements such as classes, methods, properties, among others.
Syntax of Attributes
An attribute is declared by placing the attribute’s name in square brackets ([ ]
) just before the declaration of the element to which it applies. 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 Example
class and the OldMethod
, respectively.
Using Predefined Attributes
There are many predefined attributes in .NET. Let’s take a look at some of them.
Serializable Attribute
The Serializable
attribute is used to indicate that a class can be serialized, meaning that 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 Person
class 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 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.
Definition and Use of 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 is created that derives from System.Attribute
and any necessary property or field is 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 from 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.