Atributy představují speciální metadata, která lze připojit k deklaracím typů (tříd, metod, vlastností, atd.). Umožňují rozšířit informace o kódu a tyto informace zpřístupnit za běhu pomocí reflexe. Atributy jsou třídami odvozenými z bázové třídy System.Attribute.
Účel
- Popis chování – např.
[Obsolete]označí prvek jako zastaralý. - Konfigurace knihoven a frameworků – např.
[JsonProperty]pro serializaci JSON. - Využití v reflexi – kód může na základě atributů dynamicky měnit své chování.
- Validace dat – např.
[Required],[Range]v ASP.NET. - Generování kódu – např. v nástrojích typu Source Generators.
Základní použití atributů
Příklad použití vestavěného atributu:
[Obsolete("Use method NewMethod instead of this one.")]
public void OldMethod()
{
// stará implementace
}Atributy lze aplikovat na:
- Třídy (
class) - Struktury (
struct) - Metody (
method) - Vlastnosti (
property) - Pole (
field) - Parametry (
parameter) - Celá sestavení (
assembly)
Vytvoření vlastního atributu
Definice atributu
Pro tvorbu vlastního atributu je potřebné vytvořit třídu, která bude dědit z bázové třídy Attribute. Je pravidlem, že názvy atributových třídy využívají suffix Attribute.
Při tvorbě vlastního atributu se nad deklaraci třídy umisťuje atribut AttributUsage, kterým se specifikuje, kde je možné jej vytvořený atribut využít.
[AttributeUsage(AttributeTargets.Property)]
public class DisplayNameAttribute : Attribute
{
public string Name { get; }
public DisplayNameAttribute(string name)
{
Name = name;
}
}Použití atributu
public class UserDto
{
[DisplayName("Uživatelské jméno")]
public string Username { get; set; }
[DisplayName("E-mailová adresa")]
public string Email { get; set; }
public int Age { get; set; }
}Přístup pomocí reflexe
public class AttributeReader
{
public static void PrintDisplayNames<T>()
{
var type = typeof(T);
var props = type.GetProperties();
foreach (var prop in props)
{
var attr = prop.GetCustomAttribute<DisplayNameAttribute>();
if (attr != null)
{
Console.WriteLine($"{prop.Name} → {attr.Name}");
}
else
{
Console.WriteLine($"{prop.Name} → (bez popisku)");
}
}
}
}
internal class Program
{
private static void Main()
{
AttributeReader.PrintDisplayNames<UserDto>();
}
}Výstup:
Username → Uživatelské jméno
Email → E-mailová adresa
Age → (bez popisku)