Skip to content

Commit a3d88aa

Browse files
Freshness Edit: dotnet content (#45342)
* edit pass * updates after review from BillWagner * edits after review * Apply suggestions from code review * Update docs/csharp/advanced-topics/reflection-and-attributes/index.md * add spacing around lists --------- Co-authored-by: Bill Wagner <[email protected]>
1 parent 5e2a32f commit a3d88aa

File tree

1 file changed

+98
-56
lines changed
  • docs/csharp/advanced-topics/reflection-and-attributes

1 file changed

+98
-56
lines changed
Lines changed: 98 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,131 @@
11
---
2-
title: "Attributes and reflection"
3-
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
55
---
66
# Attributes
77

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*.
99

1010
Attributes have the following properties:
1111

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.
1414
- 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.
1616

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
1818

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:
2022

2123
> [!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.
2325
2426
:::code language="csharp" source="./snippets/conceptual/Program.cs" id="GetTypeInformation":::
2527

26-
The output is: `System.Int32`.
28+
The output shows the type:
29+
30+
```output
31+
System.Int32
32+
```
2733

2834
The following example uses reflection to obtain the full name of the loaded assembly.
2935

3036
:::code language="csharp" source="./snippets/conceptual/Program.cs" id="GetAssemblyInfo":::
3137

32-
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:
3339

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>.
40+
```output
41+
System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
42+
```
3643

37-
## Using attributes
44+
### Keyword differences for IL
45+
46+
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
3852

3953
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.
4054

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:
4256

4357
:::code language="csharp" source="./snippets/conceptual/AttributesOverview.cs" id="Snippet1":::
4458

45-
A method with the attribute <xref:System.Runtime.InteropServices.DllImportAttribute> is declared like the following example:
59+
You can declare a method with the <xref:System.Runtime.InteropServices.DllImportAttribute> attribute:
4660

4761
:::code language="csharp" source="./snippets/conceptual/AttributesOverview.cs" id="Snippet2":::
4862

49-
More than one attribute can be placed on a declaration as the following example shows:
63+
You can place multiple attributes on a declaration:
5064

5165
:::code language="csharp" source="./snippets/conceptual/AttributesOverview.cs" id="Snippet4":::
5266

53-
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:
5468

5569
:::code language="csharp" source="./snippets/conceptual/AttributesOverview.cs" id="Snippet5":::
5670

5771
> [!NOTE]
58-
> 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.
5973
6074
### Attribute parameters
6175

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:
63109

64110
```csharp
65111
[DllImport("user32.dll")]
66112
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
67113
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]
68114
```
69115

70-
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).
73117

74118
### Attribute targets
75119

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.
77121

78122
To explicitly identify an attribute target, use the following syntax:
79123

80124
```csharp
81125
[target : attribute-list]
82126
```
83127

84-
The list of possible `target` values is shown in the following table.
128+
The following table shows the list of possible `target` values.
85129

86130
| Target value | Applies to |
87131
|--------------|------------------------------------------------------------------------|
@@ -95,9 +139,9 @@ The list of possible `target` values is shown in the following table.
95139
| `return` | Return value of a method, property indexer, or `get` property accessor |
96140
| `type` | Struct, class, interface, enum, or delegate |
97141

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).
99143

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).
101145

102146
```csharp
103147
using System;
@@ -111,42 +155,40 @@ The following example shows how to apply attributes to methods, method parameter
111155
:::code language="csharp" source="./snippets/conceptual/AttributesOverview.cs" id="Snippet6":::
112156

113157
> [!NOTE]
114-
> 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).
117159
118-
The following list includes a few of the common uses of attributes in code:
160+
## Review ways to use attributes
119161

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:
131163

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.
133175

134-
Reflection is useful in the following situations:
176+
## Review reflection scenarios
135177

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:
140179

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).
142184

143-
For more information:
185+
## Related links
144186

145-
- [Common Attributes (C#)](../../language-reference/attributes/global.md)
146-
- [Caller Information (C#)](../../language-reference/attributes/caller-information.md)
187+
- [Common attributes (C#)](../../language-reference/attributes/global.md)
188+
- [Caller information (C#)](../../language-reference/attributes/caller-information.md)
147189
- [Attributes](../../../standard/attributes/index.md)
148190
- [Reflection](../../../fundamentals/reflection/reflection.md)
149-
- [View Type Information](../../../fundamentals/reflection/viewing-type-information.md)
150-
- [Reflection and Generic Types](../../../fundamentals/reflection/reflection-and-generic-types.md)
191+
- [View type information](../../../fundamentals/reflection/viewing-type-information.md)
192+
- [Reflection and generic types](../../../fundamentals/reflection/reflection-and-generic-types.md)
151193
- <xref:System.Reflection.Emit>
152-
- [Retrieving Information Stored in Attributes](../../../standard/attributes/retrieving-information-stored-in-attributes.md)
194+
- [Retrieving information stored in attributes](../../../standard/attributes/retrieving-information-stored-in-attributes.md)

0 commit comments

Comments
 (0)