- You can decorate properties, classes, interfaces, structs, enums, delegates, events, methods, constructors, fields, parameters, return values, assemblies, and type parameters.
- By default, an attribute applies to the element that it precedes.
- You can also explicitly identify. E.g.,
return
attributes, appear before a method declaration but use the same type of syntax structure:
[return: Description("Returns true if the object is in a valid state.")]
public bool IsValid()
{
throw new NotImplementedException();
}
- When applying an attribute to a construct, only literal values and types (such as
typeof(int)
) are allowed as arguments.
- This is to enable their serialization into the resultant CIL.
- Therefore, it is not possible to call a static method when applying an attribute.
- Providing a constructor that takes arguments of type
DateTime
would be of little value, since there is no DateTime
literal.
Common Attributes (C#)
Custom Attributes
- The characteristic that turns a general class into an attribute is that it derives from
System.Attribute
.
Reflection: Find Decorated Classes
public static IEnumerable<Type> GetDecorated<T>(this Assembly assembly, bool inherit = true)
where T : Attribute
=> assembly.GetTypes().Where(x => x.GetCustomAttributes(typeof(T), inherit).Any());
AttributeUsage
Attribute
- If the attribute is used inappropriately it will cause a compile-time error.
- To avoid inappropriate use of an attribute, custom attributes can be decorated with
System.AttributeUsage
attribute.
AttributeUsage
attribute’s constructor takes an AttributesTargets
flag.
- This enum provides a list of all the possible targets that the runtime allows an attribute to decorate.
AllowMultiple
parameter make a custom attribute single-use or multiuse.
// Restrict the attribute to properties and methods
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]
public class CommandLineSwitchAliasAttribute : Attribute
{
// ...
}
Attribute
Static Methods
- You can check that a class has a specific attribute by calling the static
IsDefined
method on Attribute class.
var isDefined = Attribute.IsDefined(typeof(Person), typeof(SerializableAttribute));