You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Use attributes to associate metadata or declarative information with code in C#. An attribute can be queried at run time by using reflection. Reflection provides objects that describe assemblies, modules, and types in C#. If your code includes attributes, reflection enables you to access them.
4
-
ms.date: 03/15/2023
2
+
title: Attributes and reflection
3
+
description: Use attributes to associate metadata or declarative information in C#. Query attributes at run time with reflection APIs that describe assemblies, modules, and types.
4
+
ms.date: 03/14/2025
5
5
---
6
6
# Attributes
7
7
8
-
Attributes provide a powerful method of associating metadata, or declarative information, with code (assemblies, types, methods, properties, and so forth). After an attribute is associated with a program entity, the attribute can be queried at run time by using a technique called *reflection*.
8
+
Attributes provide a powerful way to associate metadata, or declarative information, with code (assemblies, types, methods, properties, and so on). After you associate an attribute with a program entity, you can query the attribute at run time by using a technique called *reflection*.
9
9
10
10
Attributes have the following properties:
11
11
12
-
- Attributes add metadata to your program. *Metadata* is information about the types defined in a program. All .NET assemblies contain a specified set of metadata that describes the types and type members defined in the assembly. You can add custom attributes to specify any additional information that is required.
13
-
-You can apply one or more attributes to entire assemblies, modules, or smaller program elements such as classes and properties.
12
+
- Attributes add metadata to your program. *Metadata* is information about the types defined in a program. All .NET assemblies contain a specified set of metadata that describes the types and type members defined in the assembly. You can add custom attributes to specify any other required information.
13
+
-Attributes can be applied to entire assemblies, modules, or smaller program elements, such as classes and properties.
14
14
- Attributes can accept arguments in the same way as methods and properties.
15
-
-Your program can examine its own metadata or the metadata in other programs by using reflection.
15
+
-Attributes enable a program to examine its own metadata or metadata in other programs by using reflection.
16
16
17
-
[Reflection](../../../fundamentals/reflection/reflection.md) provides objects (of type <xref:System.Type>) that describe assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you're using attributes in your code, reflection enables you to access them. For more information, see [Attributes](../../../standard/attributes/index.md).
17
+
## Work with reflection
18
18
19
-
Here's a simple example of reflection using the <xref:System.Object.GetType> method - inherited by all types from the `Object` base class - to obtain the type of a variable:
19
+
[Reflection](../../../fundamentals/reflection/reflection.md) APIs provided by <xref:System.Type> describe assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. When you use attributes in your code, reflection enables you to access them. For more information, see [Attributes](../../../standard/attributes/index.md).
20
+
21
+
Here's a simple example of reflection with the <xref:System.Object.GetType> method. All types from the `Object` base class inherit this method, which is used to obtain the type of a variable:
20
22
21
23
> [!NOTE]
22
-
> Make sure you add `using System;` and `using System.Reflection;` at the top of your *.cs* file.
24
+
> Make sure you add the `using System;` and `using System.Reflection;`statements at the top of your C# (*.cs*) code file.
The output is something like: `System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e`.
38
+
The output is similar to the following example:
33
39
34
-
> [!NOTE]
35
-
> The C# keywords `protected` and `internal` have no meaning in Intermediate Language (IL) and are not used in the reflection APIs. The corresponding terms in IL are *Family* and *Assembly*. To identify an `internal` method using reflection, use the <xref:System.Reflection.MethodBase.IsAssembly%2A> property. To identify a `protected internal` method, use the <xref:System.Reflection.MethodBase.IsFamilyOrAssembly%2A>.
The C# keywords `protected` and `internal` have no meaning in Intermediate Language (IL) and aren't used in the reflection APIs. The corresponding terms in IL are *Family* and *Assembly*. Here some ways you can use these terms:
47
+
48
+
- To identify an `internal` method by using reflection, use the <xref:System.Reflection.MethodBase.IsAssembly%2A> property.
49
+
- To identify a `protected internal` method, use the <xref:System.Reflection.MethodBase.IsFamilyOrAssembly%2A>.
50
+
51
+
## Work with attributes
38
52
39
53
Attributes can be placed on almost any declaration, though a specific attribute might restrict the types of declarations on which it's valid. In C#, you specify an attribute by placing the name of the attribute enclosed in square brackets (`[]`) above the declaration of the entity to which it applies.
40
54
41
-
In this example, the <xref:System.SerializableAttribute> attribute is used to apply a specific characteristic to a class:
55
+
In this example, you use the <xref:System.SerializableAttribute> attribute to apply a specific characteristic to a class:
Some attributes can be specified more than once for a given entity. An example of such a multiuse attribute is<xref:System.Diagnostics.ConditionalAttribute>:
67
+
Some attributes can be specified more than once for a given entity. The following example shows multiuse of the<xref:System.Diagnostics.ConditionalAttribute> attribute:
> By convention, all attribute names end with the word "Attribute" to distinguish them from other items in the .NET libraries. However, you do not need to specify the attribute suffix when using attributes in code. For example, `[DllImport]` is equivalent to `[DllImportAttribute]`, but `DllImportAttribute` is the attribute's actual name in the .NET Class Library.
72
+
> By convention, all attribute names end with the suffix "Attribute" to distinguish them from other types in the .NET libraries. However, you don't need to specify the attribute suffix when you use attributes in code. For example, a `[DllImport]`declaration is equivalent to a `[DllImportAttribute]` declaration, but `DllImportAttribute` is the actual name of the class in the .NET Class Library.
59
73
60
74
### Attribute parameters
61
75
62
-
Many attributes have parameters, which can be positional, unnamed, or named. Any positional parameters must be specified in a certain order and can't be omitted. Named parameters are optional and can be specified in any order. Positional parameters are specified first. For example, these three attributes are equivalent:
76
+
Many attributes have parameters, which can be *positional*, *unnamed*, or *named*. The following table describes how to work with named and positional attributes:
77
+
78
+
:::row:::
79
+
:::column span="2":::
80
+
**Positional parameters**
81
+
82
+
Parameters of the attribute constructor:
83
+
:::column-end:::
84
+
:::column span="2":::
85
+
**Named parameters**
86
+
87
+
Properties or fields of the attribute:
88
+
:::column-end:::
89
+
:::row-end:::
90
+
91
+
:::row:::
92
+
:::column span="2":::
93
+
94
+
- Must specify, can't omit
95
+
- Always specify first
96
+
- Specify in **certain** order
97
+
98
+
:::column-end:::
99
+
:::column span="2":::
100
+
101
+
- Always optional, omit when false
102
+
- Specify after positional parameters
103
+
- Specify in any order
104
+
105
+
:::column-end:::
106
+
:::row-end:::
107
+
108
+
For example, the following code shows three equivalent `DllImport` attributes:
The first parameter, the DLL name, is positional and always comes first; the others are named. In this case, both named parameters default to false, so they can be omitted. Positional parameters correspond to the parameters of the attribute constructor. Named or optional parameters correspond to either properties or fields of the attribute. Refer to the individual attribute's documentation for information on default parameter values.
71
-
72
-
For more information on allowed parameter types, see the [Attributes](~/_csharpstandard/standard/attributes.md#2224-attribute-parameter-types) section of the [C# language specification](~/_csharpstandard/standard/README.md).
116
+
The first parameter, the DLL name, is positional and always comes first. The other instances are named parameters. In this scenario, both named parameters default to false, so they can be omitted. Refer to the individual attribute's documentation for information on default parameter values. For more information on allowed parameter types, see the [Attributes](~/_csharpstandard/standard/attributes.md#2224-attribute-parameter-types) section of the [C# language specification](~/_csharpstandard/standard/README.md).
73
117
74
118
### Attribute targets
75
119
76
-
The *target* of an attribute is the entity that the attribute applies to. For example, an attribute may apply to a class, a particular method, or an entire assembly. By default, an attribute applies to the element that follows it. But you can also explicitly identify, for example, whether an attribute is applied to a method, or to its parameter, or to its return value.
120
+
The *target* of an attribute is the entity that the attribute applies to. For example, an attribute can apply to a class, a method, or an assembly. By default, an attribute applies to the element that follows it. But you can also explicitly identify the element to associate, such as a method, a parameter, or the return value.
77
121
78
122
To explicitly identify an attribute target, use the following syntax:
79
123
80
124
```csharp
81
125
[target : attribute-list]
82
126
```
83
127
84
-
The list of possible `target` values is shown in the following table.
128
+
The following table shows the list of possible `target` values.
@@ -95,9 +139,9 @@ The list of possible `target` values is shown in the following table.
95
139
|`return`| Return value of a method, property indexer, or `get` property accessor |
96
140
|`type`| Struct, class, interface, enum, or delegate |
97
141
98
-
You would specify the `field` target value to apply an attribute to the backing field created for an [automatically implemented property](../../programming-guide/classes-and-structs/properties.md).
142
+
You can specify the `field` target value to apply an attribute to the backing field created for an [automatically implemented property](../../programming-guide/classes-and-structs/properties.md).
99
143
100
-
The following example shows how to apply attributes to assemblies and modules. For more information, see [Common Attributes (C#)](../../language-reference/attributes/global.md).
144
+
The following example shows how to apply attributes to assemblies and modules. For more information, see [Common attributes (C#)](../../language-reference/attributes/global.md).
101
145
102
146
```csharp
103
147
usingSystem;
@@ -111,42 +155,40 @@ The following example shows how to apply attributes to methods, method parameter
> Regardless of the targets on which `ValidatedContract` is defined to be valid, the `return` target has to be specified, even if `ValidatedContract` were defined to apply only to return values. In other words, the compiler will not use `AttributeUsage` information to resolve ambiguous attribute targets. For more information, see [AttributeUsage](../../language-reference/attributes/general.md).
115
-
116
-
## Common uses for attributes
158
+
> Regardless of the targets on which the `ValidatedContract` attribute is defined to be valid, the `return` target has to be specified, even if the `ValidatedContract` attribute is defined to apply only to return values. In other words, the compiler doesn't use the `AttributeUsage` information to resolve ambiguous attribute targets. For more information, see [AttributeUsage](../../language-reference/attributes/general.md).
117
159
118
-
The following list includes a few of the common uses of attributes in code:
160
+
## Review ways to use attributes
119
161
120
-
- Marking methods using the `WebMethod` attribute in Web services to indicate that the method should be callable over the SOAP protocol. For more information, see <xref:System.Web.Services.WebMethodAttribute>.
121
-
- Describing how to marshal method parameters when interoperating with native code. For more information, see <xref:System.Runtime.InteropServices.MarshalAsAttribute>.
122
-
- Describing the COM properties for classes, methods, and interfaces.
123
-
- Calling unmanaged code using the <xref:System.Runtime.InteropServices.DllImportAttribute> class.
124
-
- Describing your assembly in terms of title, version, description, or trademark.
125
-
- Describing which members of a class to serialize for persistence.
126
-
- Describing how to map between class members and XML nodes for XML serialization.
127
-
- Describing the security requirements for methods.
128
-
- Specifying characteristics used to enforce security.
129
-
- Controlling optimizations by the just-in-time (JIT) compiler so the code remains easy to debug.
130
-
- Obtaining information about the caller to a method.
162
+
Here are some common ways to use attributes in code:
131
163
132
-
## Reflection overview
164
+
- Mark controller methods that respond to POST messages by using the `HttpPost` attribute. For more information, see the <xref:Microsoft.AspNetCore.Mvc.HttpPostAttribute> class.
165
+
- Describe how to marshal method parameters when interoperating with native code. For more information, see the <xref:System.Runtime.InteropServices.MarshalAsAttribute> class.
166
+
- Describe Component Object Model (COM) properties for classes, methods, and interfaces.
167
+
- Call unmanaged code by using the <xref:System.Runtime.InteropServices.DllImportAttribute> class.
168
+
- Describe your assembly in terms of title, version, description, or trademark.
169
+
- Describe which members of a class to serialize for persistence.
170
+
- Describe how to map between class members and XML nodes for XML serialization.
171
+
- Describe the security requirements for methods.
172
+
- Specify characteristics used to enforce security.
173
+
- Control optimizations with the just-in-time (JIT) compiler so the code remains easy to debug.
174
+
- Obtain information about the caller to a method.
133
175
134
-
Reflection is useful in the following situations:
176
+
## Review reflection scenarios
135
177
136
-
- When you have to access attributes in your program's metadata. For more information, see [Retrieving Information Stored in Attributes](../../../standard/attributes/retrieving-information-stored-in-attributes.md).
137
-
- For examining and instantiating types in an assembly.
138
-
- For building new types at run time. Use classes in <xref:System.Reflection.Emit>.
139
-
- For performing late binding, accessing methods on types created at run time. See the article [Dynamically Loading and Using Types](../../../fundamentals/reflection/dynamically-loading-and-using-types.md).
178
+
Reflection is useful in the following scenarios:
140
179
141
-
## Related sections
180
+
- Access attributes in your program's metadata. For more information, see [Retrieving information stored in attributes](../../../standard/attributes/retrieving-information-stored-in-attributes.md).
181
+
- Examine and instantiate types in an assembly.
182
+
- Build new types at run time by using classes in the <xref:System.Reflection.Emit> namespace.
183
+
- Perform late binding and access methods on types created at run time. For more information, see [Dynamically loading and using types](../../../fundamentals/reflection/dynamically-loading-and-using-types.md).
0 commit comments