From 9c7e7db5b5df2763cc44b16003e86ab82626b0ce Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 15:18:41 -0800 Subject: [PATCH 01/12] Add XML doc comments to DynamicMethod from dotnet-api-docs Migrate documentation from dotnet/dotnet-api-docs XML into /// comments for System.Reflection.Emit.DynamicMethod using the slash migration tool. All 48 public members now have doc comments including summary, remarks, param, returns, value, and exception tags as applicable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../System/Reflection/Emit/DynamicMethod.cs | 508 ++++++++++++++++++ 1 file changed, 508 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index 60b3586d375986..b23ece11afc94d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -10,6 +10,20 @@ namespace System.Reflection.Emit { + /// + /// Defines and represents a dynamic method that can be compiled, executed, and discarded. Discarded methods are available for garbage collection. + /// + /// + /// For more information about this API, see Supplemental API remarks for DynamicMethod. + /// + /// + /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. + /// + /// + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit + /// Walkthrough: Emitting Code in Partial Trust Scenarios public sealed partial class DynamicMethod : MethodInfo { // The context when the method was created. We use this to do the RestrictedMemberAccess checks. @@ -25,6 +39,27 @@ public sealed partial class DynamicMethod : MethodInfo // class initialization (ctor and init) // + /// + /// Initializes an anonymously hosted dynamic method, specifying the method name, return type, and parameter types. + /// + /// The name of the dynamic method. This can be a zero-length string, but it cannot be . + /// A object that specifies the return type of the dynamic method, or if the method has no return type. + /// An array of objects specifying the types of the parameters of the dynamic method, or if the method has no parameters. + /// An element of is or . + /// is . + /// .NET Framework and .NET Core versions older than 2.1: is a type for which returns . + /// + /// + /// This constructor was introduced in the .NET Framework 3.5 or later. + /// + /// The dynamic method that is created by this constructor is associated with an anonymous assembly instead of an existing type or module. The anonymous assembly exists only to provide a sandbox environment for dynamic methods, that is, to isolate them from other code. This environment makes it safe for the dynamic method to be emitted and executed by partially trusted code. + /// This constructor specifies that just-in-time (JIT) visibility checks will be enforced for the Microsoft intermediate language (MSIL) of the dynamic method. That is, the code in the dynamic method has access to public methods of public classes. Exceptions are thrown if the method tries to access types or members that are private, protected, or internal (Friend in Visual Basic). To create a dynamic method that has restricted ability to skip JIT visibility checks, use the constructor. + /// When an anonymously hosted dynamic method is constructed, the call stack of the emitting assembly is included. When the method is invoked, the permissions of the emitting assembly are used instead of the permissions of the actual caller. Thus, the dynamic method cannot execute at a higher level of privilege than that of the assembly that emitted it, even if it is passed to and executed by an assembly that has a higher trust level. + /// This constructor specifies the method attributes Public and Static, and the calling convention Standard. + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit + /// Walkthrough: Emitting Code in Partial Trust Scenarios [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] public DynamicMethod(string name, Type? returnType, @@ -41,6 +76,36 @@ public DynamicMethod(string name, true); } + /// + /// Initializes an anonymously hosted dynamic method, specifying the method name, return type, parameter types, and whether just-in-time (JIT) visibility checks should be skipped for types and members accessed by the Microsoft intermediate language (MSIL) of the dynamic method. + /// + /// The name of the dynamic method. This can be a zero-length string, but it cannot be . + /// A object that specifies the return type of the dynamic method, or if the method has no return type. + /// An array of objects specifying the types of the parameters of the dynamic method, or if the method has no parameters. + /// to skip JIT visibility checks on types and members accessed by the MSIL of the dynamic method, with this restriction: the trust level of the assemblies that contain those types and members must be equal to or less than the trust level of the call stack that emits the dynamic method; otherwise, . + /// An element of is or . + /// is . + /// .NET Framework and .NET Core versions older than 2.1: is a type for which returns . + /// + /// + /// + /// + /// This constructor was introduced in the .NET Framework 3.5 or later. + /// + /// The dynamic method that is created by this constructor is associated with an anonymous assembly instead of an existing type or module. The anonymous assembly exists only to provide a sandbox environment for dynamic methods, that is, to isolate them from other code. This environment makes it safe for the dynamic method to be emitted and executed by partially trusted code. + /// Anonymously hosted dynamic methods do not have automatic access to any types or members that are private, protected, or internal (Friend in Visual Basic). This is different from dynamic methods that are associated with an existing type or module, which have access to hidden members in their associated scope. + /// Specify true for restrictedSkipVisibility if your dynamic method has to access types or members that are private, protected, or internal. This gives the dynamic method restricted access to these members. That is, the members can be accessed only if the following conditions are met: + /// - The target members belong to an assembly that has a level of trust equal to or lower than the call stack that emits the dynamic method. + /// - The call stack that emits the dynamic method is granted with the RestrictedMemberAccess flag. This is always true when the code is executed with full trust. For partially trusted code, it is true only if the host explicitly grants the permission. + /// > If the permission has not been granted, a security exception is thrown when is called or when the dynamic method is invoked, not when this constructor is called. No special permissions are required to emit the dynamic method. + /// For example, a dynamic method that is created with restrictedSkipVisibility set to true can access a private member of any assembly on the call stack if the call stack has been granted restricted member access. If the dynamic method is created with partially trusted code on the call stack, it cannot access a private member of a type in a .NET Framework assembly, because such assemblies are fully trusted. + /// If restrictedSkipVisibility is false, JIT visibility checks are enforced. The code in the dynamic method has access to public methods of public classes, and exceptions are thrown if it tries to access types or members that are private, protected, or internal. + /// When an anonymously hosted dynamic method is constructed, the call stack of the emitting assembly is included. When the method is invoked, the permissions of the emitting call stack are used instead of the permissions of the actual caller. Thus, the dynamic method cannot execute at a higher level of privilege than that of the assembly that emitted it, even if it is passed to and executed by an assembly that has a higher trust level. + /// This constructor specifies the method attributes Public and Static, and the calling convention Standard. + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit + /// Walkthrough: Emitting Code in Partial Trust Scenarios [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] public DynamicMethod(string name, Type? returnType, @@ -58,6 +123,28 @@ public DynamicMethod(string name, true); } + /// + /// Creates a dynamic method that is global to a module, specifying the method name, return type, parameter types, and module. + /// + /// The name of the dynamic method. This can be a zero-length string, but it cannot be . + /// A object that specifies the return type of the dynamic method, or if the method has no return type. + /// An array of objects specifying the types of the parameters of the dynamic method, or if the method has no parameters. + /// A representing the module with which the dynamic method is to be logically associated. + /// An element of is or . -or- is a module that provides anonymous hosting for dynamic methods. + /// is . -or- is . + /// .NET Framework and .NET Core versions older than 2.1: is a type for which returns . + /// + /// + /// + /// This constructor specifies method attributes Public and Static, calling convention Standard, and does not skip just-in-time (JIT) visibility checks. + /// The dynamic method created with this constructor has access to public and internal (Friend in Visual Basic) members of all the types contained in module m. + /// > For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: m is a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. + /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. + /// + /// + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] public DynamicMethod(string name, Type? returnType, @@ -77,6 +164,26 @@ public DynamicMethod(string name, false); } + /// + /// Creates a dynamic method that is global to a module, specifying the method name, return type, parameter types, module, and whether just-in-time (JIT) visibility checks should be skipped for types and members accessed by the Microsoft intermediate language (MSIL) of the dynamic method. + /// + /// The name of the dynamic method. This can be a zero-length string, but it cannot be . + /// A object that specifies the return type of the dynamic method, or if the method has no return type. + /// An array of objects specifying the types of the parameters of the dynamic method, or if the method has no parameters. + /// A representing the module with which the dynamic method is to be logically associated. + /// to skip JIT visibility checks on types and members accessed by the MSIL of the dynamic method. + /// An element of is or . -or- is a module that provides anonymous hosting for dynamic methods. + /// is . -or- is . + /// .NET Framework and .NET Core versions older than 2.1: is a type for which returns . + /// + /// + /// For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: m is a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. + /// + /// This constructor specifies method attributes Public and Static, and calling convention Standard. + /// The dynamic method created with this constructor has access to public and internal (Friend in Visual Basic) members of all the types in contained module m. Skipping the JIT compiler's visibility checks allows the dynamic method to access private and protected members of all other types as well. This is useful, for example, when writing code to serialize objects. + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] public DynamicMethod(string name, Type? returnType, @@ -97,6 +204,28 @@ public DynamicMethod(string name, false); } + /// + /// Creates a dynamic method that is global to a module, specifying the method name, attributes, calling convention, return type, parameter types, module, and whether just-in-time (JIT) visibility checks should be skipped for types and members accessed by the Microsoft intermediate language (MSIL) of the dynamic method. + /// + /// The name of the dynamic method. This can be a zero-length string, but it cannot be . + /// A bitwise combination of values that specifies the attributes of the dynamic method. The only combination allowed is and . + /// The calling convention for the dynamic method. Must be . + /// A object that specifies the return type of the dynamic method, or if the method has no return type. + /// An array of objects specifying the types of the parameters of the dynamic method, or if the method has no parameters. + /// A representing the module with which the dynamic method is to be logically associated. + /// to skip JIT visibility checks on types and members accessed by the MSIL of the dynamic method; otherwise, . + /// An element of is or . -or- is a module that provides anonymous hosting for dynamic methods. + /// is . -or- is . + /// is a combination of flags other than and . -or- is not . -or- is a type for which returns . + /// + /// + /// For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: m is a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. + /// + /// The dynamic method created with this constructor has access to public and internal (Friend in Visual Basic) members of all the public and internal types contained in module m. + /// Skipping the JIT compiler's visibility checks allows the dynamic method to access private and protected members of all other types in the module and in all other assemblies as well. This is useful, for example, when writing code to serialize objects. + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] public DynamicMethod(string name, MethodAttributes attributes, @@ -119,6 +248,38 @@ public DynamicMethod(string name, false); } + /// + /// Creates a dynamic method, specifying the method name, return type, parameter types, and the type with which the dynamic method is logically associated. + /// + /// The name of the dynamic method. This can be a zero-length string, but it cannot be . + /// A object that specifies the return type of the dynamic method, or if the method has no return type. + /// An array of objects specifying the types of the parameters of the dynamic method, or if the method has no parameters. + /// A with which the dynamic method is logically associated. The dynamic method has access to all members of the type. + /// An element of is or . -or- is an interface, an array, an open generic type, or a type parameter of a generic type or method. + /// is . -or- is . + /// .NET Framework and .NET Core versions older than 2.1: is a type for which returns . + /// + /// + /// For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: owner is in a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. + /// + /// + /// In general, changing the internal fields of classes is not good object-oriented coding practice. + /// + /// + /// This is an example of the relaxed rules for delegate binding introduced in .NET Framework 2.0, along with new overloads of the CreateDelegate method. For more information, see the class. + /// + /// The dynamic method created with this constructor has access to all members of the type owner, and to public and internal (Friend in Visual Basic) members of all the other types in the module that contains owner. + /// This constructor specifies method attributes Public and Static, calling convention Standard, and does not skip just-in-time (JIT) visibility checks. + /// The following code example creates a that is logically associated with a type. This association gives it access to the private members of that type. + /// The code example defines a class named Example with a private field, a class named DerivedFromExample that derives from the first class, a delegate type named UseLikeStatic that returns and has parameters of type Example and , and a delegate type named UseLikeInstance that returns and has one parameter of type . + /// The example code then creates a that changes the private field of an instance of Example and returns the previous value. + /// The example code creates an instance of Example and then creates two delegates. The first is of type UseLikeStatic, which has the same parameters as the dynamic method. The second is of type UseLikeInstance, which lacks the first parameter (of type Example). This delegate is created using the method overload; the second parameter of that method overload is an instance of Example, in this case the instance just created, which is bound to the newly created delegate. Whenever that delegate is invoked, the dynamic method acts on the bound instance of Example. + /// The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromExample, and the delegate calls are repeated. + /// + /// + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] public DynamicMethod(string name, Type? returnType, @@ -138,6 +299,26 @@ public DynamicMethod(string name, false); } + /// + /// Creates a dynamic method, specifying the method name, return type, parameter types, the type with which the dynamic method is logically associated, and whether just-in-time (JIT) visibility checks should be skipped for types and members accessed by the Microsoft intermediate language (MSIL) of the dynamic method. + /// + /// The name of the dynamic method. This can be a zero-length string, but it cannot be . + /// A object that specifies the return type of the dynamic method, or if the method has no return type. + /// An array of objects specifying the types of the parameters of the dynamic method, or if the method has no parameters. + /// A with which the dynamic method is logically associated. The dynamic method has access to all members of the type. + /// to skip JIT visibility checks on types and members accessed by the MSIL of the dynamic method; otherwise, . + /// An element of is or . -or- is an interface, an array, an open generic type, or a type parameter of a generic type or method. + /// is . -or- is . + /// .NET Framework and .NET Core versions older than 2.1: is a type for which returns . + /// + /// + /// For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: owner is in a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. + /// + /// The dynamic method created with this constructor has access to all members of the type owner, and to public and internal (Friend in Visual Basic) members of all the other types in the module that contains owner. Skipping the JIT compiler's visibility checks allows the dynamic method to access private and protected members of all other types as well. This is useful, for example, when writing code to serialize objects. + /// This constructor specifies method attributes Public and Static, and calling convention Standard. + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] public DynamicMethod(string name, Type? returnType, @@ -158,6 +339,28 @@ public DynamicMethod(string name, false); } + /// + /// Creates a dynamic method, specifying the method name, attributes, calling convention, return type, parameter types, the type with which the dynamic method is logically associated, and whether just-in-time (JIT) visibility checks should be skipped for types and members accessed by the Microsoft intermediate language (MSIL) of the dynamic method. + /// + /// The name of the dynamic method. This can be a zero-length string, but it cannot be . + /// A bitwise combination of values that specifies the attributes of the dynamic method. The only combination allowed is and . + /// The calling convention for the dynamic method. Must be . + /// A object that specifies the return type of the dynamic method, or if the method has no return type. + /// An array of objects specifying the types of the parameters of the dynamic method, or if the method has no parameters. + /// A with which the dynamic method is logically associated. The dynamic method has access to all members of the type. + /// to skip JIT visibility checks on types and members accessed by the MSIL of the dynamic method; otherwise, . + /// An element of is or . -or- is an interface, an array, an open generic type, or a type parameter of a generic type or method. + /// is . -or- is . + /// is a combination of flags other than and . -or- is not . -or- is a type for which returns . + /// + /// + /// For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: owner is in a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. + /// + /// The dynamic method is global to the module that contains the type owner. It has access to all members of the type owner. + /// The dynamic method created with this constructor has access to all members of the type owner, and to public and internal (Friend in Visual Basic) members of all the types contained in the module that contains owner. Skipping the JIT compiler's visibility checks allows the dynamic method to access private and protected members of all other types as well. This is useful, for example, when writing code to serialize objects. + /// + /// How to: Define and Execute Dynamic Methods + /// Security Issues in Reflection Emit [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] public DynamicMethod(string name, MethodAttributes attributes, @@ -297,6 +500,16 @@ private void Init(string name, // MethodInfo api. // + /// + /// Returns the signature of the method, represented as a string. + /// + /// A string representing the method signature. + /// + /// The signature includes only types and the method name, if any. Parameter names are not included. + /// The following code example displays the method of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override string ToString() { var sbName = new ValueStringBuilder(MethodNameBufferSize); @@ -312,37 +525,243 @@ public override string ToString() return sbName.ToString(); } + /// + /// Gets the name of the dynamic method. + /// + /// The simple name of the method. + /// + /// + /// It is not necessary to name dynamic methods. + /// + /// The following code example displays the name of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override string Name => _name; + /// + /// Gets the type that declares the method, which is always for dynamic methods. + /// + /// Always . + /// + /// This property always returns null for dynamic methods. Even when a dynamic method is logically associated with a type, it is not declared by the type. + /// The following code example displays the declaring type of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override Type? DeclaringType => null; + /// + /// Gets the class that was used in reflection to obtain the method. + /// + /// Always . + /// + /// This property always returns null for dynamic methods. + /// The following code example displays the reflected type of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override Type? ReflectedType => null; + /// + /// Gets the module with which the dynamic method is logically associated. + /// + /// The with which the current dynamic method is associated. + /// + /// If a module was specified when the dynamic method was created, this property returns that module. If a type was specified as the owner when the dynamic method was created, this property returns the module that contains that type. + /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override Module Module => _module; // we cannot return a MethodHandle because we cannot track it via GC so this method is off limits + /// + /// Not supported for dynamic methods. + /// + /// Not supported for dynamic methods. + /// Not allowed for dynamic methods. public override RuntimeMethodHandle MethodHandle => throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInDynamicMethod); + /// + /// Gets the attributes specified when the dynamic method was created. + /// + /// A bitwise combination of the values representing the attributes for the method. + /// + /// Currently, the method attributes for a dynamic method are always and . + /// The following code example displays the method attributes of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override MethodAttributes Attributes => _attributes; + /// + /// Gets the calling convention specified when the dynamic method was created. + /// + /// One of the values that indicates the calling convention of the method. + /// + /// Currently, the calling convention for a dynamic method is always . + /// The following code example displays the calling convention of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override CallingConventions CallingConvention => _callingConvention; + /// + /// Returns the base implementation for the method. + /// + /// The base implementation of the method. + /// + /// This method always returns the current DynamicMethod object. + /// public override MethodInfo GetBaseDefinition() => this; + /// + /// Returns the parameters of the dynamic method. + /// + /// An array of objects that represent the parameters of the dynamic method. + /// + /// The objects returned by this method are for information only. Use the method to set or change the characteristics of the parameters. + /// The following code example displays the parameters of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override ParameterInfo[] GetParameters() => GetParametersAsSpan().ToArray(); internal override ReadOnlySpan GetParametersAsSpan() => LoadParameters(); + /// + /// Returns the implementation flags for the method. + /// + /// A bitwise combination of values representing the implementation flags for the method. + /// + /// Currently, method implementation attributes for dynamic methods are always and . + /// public override MethodImplAttributes GetMethodImplementationFlags() => MethodImplAttributes.IL | MethodImplAttributes.NoInlining; + /// + /// Gets a value that indicates whether the current dynamic method is security-critical or security-safe-critical, and therefore can perform critical operations. + /// + /// if the current dynamic method is security-critical or security-safe-critical; if it is transparent. + /// The dynamic method doesn't have a method body. + /// + /// + /// + /// The , , and properties report the transparency level of the dynamic method as determined by the common language runtime (CLR). The combinations of these properties are shown in the following table: + /// |Security level|IsSecurityCritical|IsSecuritySafeCritical|IsSecurityTransparent| + /// |--------------------|------------------------|----------------------------|---------------------------| + /// |Critical|true|false|false| + /// |Safe critical|true|true|false| + /// |Transparent|false|false|true| + /// Using these properties is much simpler than examining the security annotations of an assembly and its types, checking the current trust level, and attempting to duplicate the runtime's rules. + /// The transparency of a dynamic method depends on the module it is associated with. If the dynamic method is associated with a type rather than a module, its transparency depends on the module that contains the type. Dynamic methods do not have security annotations, so they are assigned the default transparency for the associated module. + /// - Anonymously hosted dynamic methods are always transparent, because the system-provided module that contains them is transparent. + /// - The transparency of a dynamic method that is associated with a trusted assembly (that is, a strong-named assembly that is installed in the global assembly cache) is described in the following table. + /// |Assembly annotation|Level 1 transparency|Level 2 transparency| + /// |-------------------------|--------------------------|--------------------------| + /// |Fully transparent|Transparent|Transparent| + /// |Fully critical|Critical|Critical| + /// |Mixed transparency|Transparent|Transparent| + /// |Security-agnostic|Safe-critical|Critical| + /// For example, if you associate a dynamic method with a type that is in mscorlib.dll, which has level 2 mixed transparency, the dynamic method is transparent and cannot execute critical code. For information about transparency levels, see [Security-Transparent Code, Level 1](/dotnet/framework/misc/security-transparent-code-level-1) and [Security-Transparent Code, Level 2](/dotnet/framework/misc/security-transparent-code-level-2). + /// > Associating a dynamic method with a module in a trusted level 1 assembly that is security-agnostic, such as System.dll, does not permit elevation of trust. If the grant set of the code that calls the dynamic method does not include the grant set of System.dll (that is, full trust), is thrown when the dynamic method is called. + /// - The transparency of a dynamic method that is associated with a partially trusted assembly depends on how the assembly is loaded. If the assembly is loaded with partial trust (for example, into a sandboxed application domain), the runtime ignores the security annotations of the assembly. The assembly and all its types and members, including dynamic methods, are treated as transparent. The runtime pays attention to security annotations only if the partial-trust assembly is loaded with full trust (for example, into the default application domain of a desktop application). In that case, the runtime assigns the dynamic method the default transparency for methods according to the assembly's annotations. + /// For more information about reflection emit and transparency, see [Security Issues in Reflection Emit](/dotnet/framework/reflection-and-codedom/security-issues-in-reflection-emit). For information about transparency, see [Security Changes](/dotnet/framework/security/security-changes). + /// + /// Security Issues in Reflection Emit + /// Security Considerations for Reflection + /// Security Changes in the .NET Framework Version 4.0 + /// Security-Transparent Code, Level 1 + /// Security-Transparent Code, Level 2 public override bool IsSecurityCritical => true; + /// + /// Gets a value that indicates whether the current dynamic method is security-safe-critical at the current trust level; that is, whether it can perform critical operations and can be accessed by transparent code. + /// + /// if the dynamic method is security-safe-critical at the current trust level; if it is security-critical or transparent. + /// The dynamic method doesn't have a method body. + /// + /// + /// + /// The , , and properties report the transparency level of the dynamic method as determined by the common language runtime (CLR). The combinations of these properties are shown in the following table: + /// |Security level|IsSecurityCritical|IsSecuritySafeCritical|IsSecurityTransparent| + /// |--------------------|------------------------|----------------------------|---------------------------| + /// |Critical|true|false|false| + /// |Safe critical|true|true|false| + /// |Transparent|false|false|true| + /// Using these properties is much simpler than examining the security annotations of an assembly and its types, checking the current trust level, and attempting to duplicate the runtime's rules. + /// The transparency of a dynamic method depends on the module it is associated with. If the dynamic method is associated with a type rather than a module, its transparency depends on the module that contains the type. Dynamic methods do not have security annotations, so they are assigned the default transparency for the associated module. + /// - Anonymously hosted dynamic methods are always transparent, because the system-provided module that contains them is transparent. + /// - The transparency of a dynamic method that is associated with a trusted assembly (that is, a strong-named assembly that is installed in the global assembly cache) is described in the following table. + /// |Assembly annotation|Level 1 transparency|Level 2 transparency| + /// |-------------------------|--------------------------|--------------------------| + /// |Fully transparent|Transparent|Transparent| + /// |Fully critical|Critical|Critical| + /// |Mixed transparency|Transparent|Transparent| + /// |Security-agnostic|Safe-critical|Critical| + /// For example, if you associate a dynamic method with a type that is in mscorlib.dll, which has level 2 mixed transparency, the dynamic method is transparent and cannot execute critical code. For information about transparency levels, see [Security-Transparent Code, Level 1](/dotnet/framework/misc/security-transparent-code-level-1) and [Security-Transparent Code, Level 2](/dotnet/framework/misc/security-transparent-code-level-2). + /// > Associating a dynamic method with a module in a trusted level 1 assembly that is security-agnostic, such as System.dll, does not permit elevation of trust. If the grant set of the code that calls the dynamic method does not include the grant set of System.dll (that is, full trust), is thrown when the dynamic method is called. + /// - The transparency of a dynamic method that is associated with a partially trusted assembly depends on how the assembly is loaded. If the assembly is loaded with partial trust (for example, into a sandboxed application domain), the runtime ignores the security annotations of the assembly. The assembly and all its types and members, including dynamic methods, are treated as transparent. The runtime pays attention to security annotations only if the partial-trust assembly is loaded with full trust (for example, into the default application domain of a desktop application). In that case, the runtime assigns the dynamic method the default transparency for methods according to the assembly's annotations. + /// For more information about reflection emit and transparency, see [Security Issues in Reflection Emit](/dotnet/framework/reflection-and-codedom/security-issues-in-reflection-emit). For information about transparency, see [Security Changes](/dotnet/framework/security/security-changes). + /// + /// Security Issues in Reflection Emit + /// Security Considerations for Reflection + /// Security Changes in the .NET Framework Version 4.0 + /// Security-Transparent Code, Level 1 + /// Security-Transparent Code, Level 2 public override bool IsSecuritySafeCritical => false; + /// + /// Gets a value that indicates whether the current dynamic method is transparent at the current trust level, and therefore cannot perform critical operations. + /// + /// if the dynamic method is security-transparent at the current trust level; otherwise, . + /// The dynamic method doesn't have a method body. + /// + /// + /// + /// The , , and properties report the transparency level of the dynamic method as determined by the common language runtime (CLR). The combinations of these properties are shown in the following table: + /// |Security level|IsSecurityCritical|IsSecuritySafeCritical|IsSecurityTransparent| + /// |--------------------|------------------------|----------------------------|---------------------------| + /// |Critical|true|false|false| + /// |Safe critical|true|true|false| + /// |Transparent|false|false|true| + /// Using these properties is much simpler than examining the security annotations of an assembly and its types, checking the current trust level, and attempting to duplicate the runtime's rules. + /// The transparency of a dynamic method depends on the module it is associated with. If the dynamic method is associated with a type rather than a module, its transparency depends on the module that contains the type. Dynamic methods do not have security annotations, so they are assigned the default transparency for the associated module. + /// - Anonymously hosted dynamic methods are always transparent, because the system-provided module that contains them is transparent. + /// - The transparency of a dynamic method that is associated with a trusted assembly (that is, a strong-named assembly that is installed in the global assembly cache) is described in the following table. + /// |Assembly annotation|Level 1 transparency|Level 2 transparency| + /// |-------------------------|--------------------------|--------------------------| + /// |Fully transparent|Transparent|Transparent| + /// |Fully critical|Critical|Critical| + /// |Mixed transparency|Transparent|Transparent| + /// |Security-agnostic|Safe-critical|Critical| + /// For example, if you associate a dynamic method with a type that is in mscorlib.dll, which has level 2 mixed transparency, the dynamic method is transparent and cannot execute critical code. For information about transparency levels, see [Security-Transparent Code, Level 1](/dotnet/framework/misc/security-transparent-code-level-1) and [Security-Transparent Code, Level 2](/dotnet/framework/misc/security-transparent-code-level-2). + /// > Associating a dynamic method with a module in a trusted level 1 assembly that is security-agnostic, such as System.dll, does not permit elevation of trust. If the grant set of the code that calls the dynamic method does not include the grant set of System.dll (that is, full trust), is thrown when the dynamic method is called. + /// - The transparency of a dynamic method that is associated with a partially trusted assembly depends on how the assembly is loaded. If the assembly is loaded with partial trust (for example, into a sandboxed application domain), the runtime ignores the security annotations of the assembly. The assembly and all its types and members, including dynamic methods, are treated as transparent. The runtime pays attention to security annotations only if the partial-trust assembly is loaded with full trust (for example, into the default application domain of a desktop application). In that case, the runtime assigns the dynamic method the default transparency for methods according to the assembly's annotations. + /// For more information about reflection emit and transparency, see [Security Issues in Reflection Emit](/dotnet/framework/reflection-and-codedom/security-issues-in-reflection-emit). For information about transparency, see [Security Changes](/dotnet/framework/security/security-changes). + /// + /// Security Issues in Reflection Emit + /// Security Considerations for Reflection + /// Security Changes in the .NET Framework Version 4.0 + /// Security-Transparent Code, Level 1 + /// Security-Transparent Code, Level 2 public override bool IsSecurityTransparent => false; + /// + /// Returns the custom attributes of the specified type that have been applied to the method. + /// + /// A representing the type of custom attribute to return. + /// to search the method's inheritance chain to find the custom attributes; to check only the current method. + /// An array of objects representing the attributes of the method that are of type or derive from type . + /// is . + /// + /// + /// Custom attributes are not currently supported on dynamic methods. The only attribute returned is ; you can get the method implementation flags more easily using the method. + /// + /// For dynamic methods, specifying true for inherit has no effect, because the method is not declared in a type. + /// public override object[] GetCustomAttributes(Type attributeType, bool inherit) { ArgumentNullException.ThrowIfNull(attributeType); @@ -359,12 +778,35 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit) return result; } + /// + /// Returns all the custom attributes defined for the method. + /// + /// to search the method's inheritance chain to find the custom attributes; to check only the current method. + /// An array of objects representing all the custom attributes of the method. + /// + /// + /// Custom attributes are not currently supported on dynamic methods. The only attribute returned is ; you can get the method implementation flags more easily using the method. + /// + /// For dynamic methods, specifying true for inherit has no effect, because the method is not declared in a type. + /// public override object[] GetCustomAttributes(bool inherit) { // support for MethodImplAttribute PCA return [new MethodImplAttribute((MethodImplOptions)GetMethodImplementationFlags())]; } + /// + /// Indicates whether the specified custom attribute type is defined. + /// + /// A representing the type of custom attribute to search for. + /// to search the method's inheritance chain to find the custom attributes; to check only the current method. + /// if the specified custom attribute type is defined; otherwise, . + /// + /// + /// Custom attributes are not currently supported on dynamic methods. + /// + /// For dynamic methods, specifying true for inherit has no effect. Dynamic methods have no inheritance chain. + /// public override bool IsDefined(Type attributeType, bool inherit) { ArgumentNullException.ThrowIfNull(attributeType); @@ -372,16 +814,58 @@ public override bool IsDefined(Type attributeType, bool inherit) return attributeType.IsAssignableFrom(typeof(MethodImplAttribute)); } + /// + /// Gets the type of return value for the dynamic method. + /// + /// A representing the type of the return value of the current method; if the method has no return type. + /// + /// If null was specified for the return type when the dynamic method was created, this property returns Void. + /// The following code example displays the return type of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override Type ReturnType => _returnType; + /// + /// Gets the return parameter of the dynamic method. + /// + /// Always . + /// + /// This property always returns null for dynamic methods. + /// public override ParameterInfo ReturnParameter => new RuntimeParameterInfo(this, null, _returnType, -1); + /// + /// Gets the custom attributes of the return type for the dynamic method. + /// + /// An representing the custom attributes of the return type for the dynamic method. + /// + /// Custom attributes are not supported on the return type of a dynamic method, so the array of custom attributes returned by the method is always empty. + /// The following code example shows how to display the custom attributes of the return type of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public override ICustomAttributeProvider ReturnTypeCustomAttributes => new EmptyCAHolder(); // // DynamicMethod specific methods // + /// + /// Defines a parameter of the dynamic method. + /// + /// The position of the parameter in the parameter list. Parameters are indexed beginning with the number 1 for the first parameter. + /// A bitwise combination of values that specifies the attributes of the parameter. + /// The name of the parameter. The name can be a zero-length string. + /// Always returns . + /// The method has no parameters. -or- is less than 0. -or- is greater than the number of the method's parameters. + /// + /// If position is 0, the method refers to the return value. Setting parameter information has no effect on the return value. + /// If the dynamic method has already been completed, by calling the or method, the method has no effect. No exception is thrown. + /// The following code example shows how to define parameter information for a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public ParameterBuilder? DefineParameter(int position, ParameterAttributes attributes, string? parameterName) { if (position < 0 || position > _parameterTypes.Length) @@ -397,11 +881,35 @@ public override bool IsDefined(Type attributeType, bool inherit) return null; } + /// + /// Returns a Microsoft intermediate language (MSIL) generator for the method with a default MSIL stream size of 64 bytes. + /// + /// An object for the method. + /// + /// + /// There are restrictions on unverifiable code in dynamic methods, even in some full-trust scenarios. See the "Verification" section in Remarks for . + /// + /// After a dynamic method has been completed, by calling the or method, any further attempt to add MSIL is ignored. No exception is thrown. + /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. + /// + /// + /// + /// How to: Define and Execute Dynamic Methods public ILGenerator GetILGenerator() { return GetILGenerator(64); } + /// + /// Gets or sets a value indicating whether the local variables in the method are zero-initialized. + /// + /// if the local variables in the method are zero-initialized; otherwise, . The default is . + /// + /// If this property is set to true, the emitted Microsoft intermediate language (MSIL) includes initialization of local variables. If it is set to false, local variables are not initialized and the generated code is unverifiable. + /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. + /// + /// + /// public bool InitLocals { get => _initLocals; From 35e5e4d8aa30c7ca855db0c28e97b483b56de533 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 16:19:45 -0800 Subject: [PATCH 02/12] Add DynamicMethod samples file and update code references Create DynamicMethod.Examples.cs with #region blocks for per-member code examples. Replace ~/snippets/ paths from dotnet-api-docs with relative paths to the local samples file. Drop VB sample references. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Reflection/Emit/DynamicMethod.Examples.cs | 210 ++++++++++++++++++ .../System/Reflection/Emit/DynamicMethod.cs | 47 +--- 2 files changed, 222 insertions(+), 35 deletions(-) create mode 100644 src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs new file mode 100644 index 00000000000000..449e84905fd941 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs @@ -0,0 +1,210 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// This file contains code examples for XML documentation. +// The examples are referenced by the DynamicMethod class documentation using #region names. + +#pragma warning disable CS8321 // Local function is declared but never used + +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace System.Reflection.Emit.Examples +{ + internal static class DynamicMethodExamples + { + private static void Examples() + { + // Note: 'hello' represents a DynamicMethod instance used in the examples below + + #region Name + // Display the name specified when the dynamic method was created. + // Note that the name can be blank. + Console.WriteLine("\r\nName: {0}", hello.Name); + #endregion + + #region DeclaringType + // Display the declaring type, which is always null for dynamic + // methods. + if (hello.DeclaringType == null) + { + Console.WriteLine("\r\nDeclaringType is always null for dynamic methods."); + } + else + { + Console.WriteLine("DeclaringType: {0}", hello.DeclaringType); + } + #endregion + + #region ReflectedType + // For dynamic methods, the reflected type is always null. + if (hello.ReflectedType == null) + { + Console.WriteLine("\r\nReflectedType is null."); + } + else + { + Console.WriteLine("\r\nReflectedType: {0}", hello.ReflectedType); + } + #endregion + + #region Module + // Display the module specified when the dynamic method was created. + Console.WriteLine("\r\nModule: {0}", hello.Module); + #endregion + + #region Attributes + // Display MethodAttributes for the dynamic method, set when + // the dynamic method was created. + Console.WriteLine("\r\nMethod Attributes: {0}", hello.Attributes); + #endregion + + #region CallingConvention + // Display the calling convention of the dynamic method, set when the + // dynamic method was created. + Console.WriteLine("\r\nCalling convention: {0}", hello.CallingConvention); + #endregion + + #region GetParameters + // Display parameter information. + ParameterInfo[] parameters = hello.GetParameters(); + Console.WriteLine("\r\nParameters: name, type, ParameterAttributes"); + foreach (ParameterInfo p in parameters) + { + Console.WriteLine("\t{0}, {1}, {2}", + p.Name, p.ParameterType, p.Attributes); + } + #endregion + + #region ReturnType + // If the method has no return type, ReturnType is System.Void. + Console.WriteLine("\r\nReturn type: {0}", hello.ReturnType); + #endregion + + #region ReturnParameter + if (hello.ReturnParameter == null) + { + Console.WriteLine("\r\nMethod has no return parameter."); + } + else + { + Console.WriteLine("\r\nReturn parameter: {0}", hello.ReturnParameter); + } + #endregion + + #region ReturnTypeCustomAttributes + // ReturnTypeCustomAttributes returns an ICustomAttributeProvider + // that can be used to enumerate the custom attributes of the + // return value. At present, there is no way to set such custom + // attributes, so the list is empty. + if (hello.ReturnType == typeof(void)) + { + Console.WriteLine("The method has no return type."); + } + else + { + ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes; + object[] returnAttributes = caProvider.GetCustomAttributes(true); + if (returnAttributes.Length == 0) + { + Console.WriteLine("\r\nThe return type has no custom attributes."); + } + else + { + Console.WriteLine("\r\nThe return type has the following custom attributes:"); + foreach (object attr in returnAttributes) + { + Console.WriteLine("\t{0}", attr.ToString()); + } + } + } + #endregion + + #region DefineParameter + // Add parameter information to the dynamic method. (This is not + // necessary, but can be useful for debugging.) For each parameter, + // identified by position, supply the parameter attributes and a + // parameter name. + hello.DefineParameter(1, ParameterAttributes.In, "message"); + hello.DefineParameter(2, ParameterAttributes.In, "valueToReturn"); + #endregion + + #region ToString + Console.WriteLine("\r\nToString: {0}", hello.ToString()); + #endregion + + #region InitLocals + // Display the default value for InitLocals. + if (hello.InitLocals) + { + Console.Write("\r\nThis method contains verifiable code."); + } + else + { + Console.Write("\r\nThis method contains unverifiable code."); + } + Console.WriteLine(" (InitLocals = {0})", hello.InitLocals); + #endregion + + #region GetILGenerator + // Create an array that specifies the parameter types of the + // overload of Console.WriteLine to be used in Hello. + Type[] writeStringArgs = {typeof(string)}; + // Get the overload of Console.WriteLine that has one + // String parameter. + MethodInfo writeString = typeof(Console).GetMethod("WriteLine", + writeStringArgs); + + // Get an ILGenerator and emit a body for the dynamic method, + // using a stream size larger than the IL that will be + // emitted. + ILGenerator il = hello.GetILGenerator(256); + // Load the first argument, which is a string, onto the stack. + il.Emit(OpCodes.Ldarg_0); + // Call the overload of Console.WriteLine that prints a string. + il.EmitCall(OpCodes.Call, writeString, null); + // The Hello method returns the value of the second argument; + // to do this, load the onto the stack and return. + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ret); + #endregion + + #region CreateDelegate + // Create a delegate that represents the dynamic method. This + // action completes the method. Any further attempts to + // change the method are ignored. + HelloDelegate hi = + (HelloDelegate) hello.CreateDelegate(typeof(HelloDelegate)); + + // Use the delegate to execute the dynamic method. + Console.WriteLine("\r\nUse the delegate to execute the dynamic method:"); + int retval = hi("\r\nHello, World!", 42); + Console.WriteLine("Invoking delegate hi(\"Hello, World!\", 42) returned: " + retval); + + // Execute it again, with different arguments. + retval = hi("\r\nHi, Mom!", 5280); + Console.WriteLine("Invoking delegate hi(\"Hi, Mom!\", 5280) returned: " + retval); + #endregion + + #region Invoke + Console.WriteLine("\r\nUse the Invoke method to execute the dynamic method:"); + // Create an array of arguments to use with the Invoke method. + object[] invokeArgs = {"\r\nHello, World!", 42}; + // Invoke the dynamic method using the arguments. This is much + // slower than using the delegate, because you must create an + // array to contain the arguments, and value-type arguments + // must be boxed. + object objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new System.Globalization.CultureInfo("en-us")); + Console.WriteLine("hello.Invoke returned: " + objRet); + #endregion + } + + // Placeholder for the DynamicMethod variable used in examples + private static DynamicMethod hello = null!; + + // Declare a delegate type that can be used to execute the completed + // dynamic method. + private delegate int HelloDelegate(string msg, int ret); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index b23ece11afc94d..3b15f39103252d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -16,11 +16,6 @@ namespace System.Reflection.Emit /// /// For more information about this API, see Supplemental API remarks for DynamicMethod. /// - /// - /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. - /// - /// - /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit /// Walkthrough: Emitting Code in Partial Trust Scenarios @@ -140,8 +135,6 @@ public DynamicMethod(string name, /// The dynamic method created with this constructor has access to public and internal (Friend in Visual Basic) members of all the types contained in module m. /// > For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: m is a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. - /// - /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -275,8 +268,6 @@ public DynamicMethod(string name, /// The example code then creates a that changes the private field of an instance of Example and returns the previous value. /// The example code creates an instance of Example and then creates two delegates. The first is of type UseLikeStatic, which has the same parameters as the dynamic method. The second is of type UseLikeInstance, which lacks the first parameter (of type Example). This delegate is created using the method overload; the second parameter of that method overload is an instance of Example, in this case the instance just created, which is bound to the newly created delegate. Whenever that delegate is invoked, the dynamic method acts on the bound instance of Example. /// The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromExample, and the delegate calls are repeated. - /// - /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -507,8 +498,7 @@ private void Init(string name, /// /// The signature includes only types and the method name, if any. Parameter names are not included. /// The following code example displays the method of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override string ToString() { @@ -534,8 +524,7 @@ public override string ToString() /// It is not necessary to name dynamic methods. /// /// The following code example displays the name of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override string Name => _name; @@ -546,8 +535,7 @@ public override string ToString() /// /// This property always returns null for dynamic methods. Even when a dynamic method is logically associated with a type, it is not declared by the type. /// The following code example displays the declaring type of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override Type? DeclaringType => null; @@ -558,8 +546,7 @@ public override string ToString() /// /// This property always returns null for dynamic methods. /// The following code example displays the reflected type of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override Type? ReflectedType => null; @@ -570,8 +557,7 @@ public override string ToString() /// /// If a module was specified when the dynamic method was created, this property returns that module. If a type was specified as the owner when the dynamic method was created, this property returns the module that contains that type. /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override Module Module => _module; @@ -590,8 +576,7 @@ public override string ToString() /// /// Currently, the method attributes for a dynamic method are always and . /// The following code example displays the method attributes of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override MethodAttributes Attributes => _attributes; @@ -602,8 +587,7 @@ public override string ToString() /// /// Currently, the calling convention for a dynamic method is always . /// The following code example displays the calling convention of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override CallingConventions CallingConvention => _callingConvention; @@ -623,8 +607,7 @@ public override string ToString() /// /// The objects returned by this method are for information only. Use the method to set or change the characteristics of the parameters. /// The following code example displays the parameters of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override ParameterInfo[] GetParameters() => GetParametersAsSpan().ToArray(); @@ -821,8 +804,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// /// If null was specified for the return type when the dynamic method was created, this property returns Void. /// The following code example displays the return type of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override Type ReturnType => _returnType; @@ -842,8 +824,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// /// Custom attributes are not supported on the return type of a dynamic method, so the array of custom attributes returned by the method is always empty. /// The following code example shows how to display the custom attributes of the return type of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public override ICustomAttributeProvider ReturnTypeCustomAttributes => new EmptyCAHolder(); @@ -863,8 +844,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// If position is 0, the method refers to the return value. Setting parameter information has no effect on the return value. /// If the dynamic method has already been completed, by calling the or method, the method has no effect. No exception is thrown. /// The following code example shows how to define parameter information for a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public ParameterBuilder? DefineParameter(int position, ParameterAttributes attributes, string? parameterName) { @@ -891,8 +871,6 @@ public override bool IsDefined(Type attributeType, bool inherit) /// /// After a dynamic method has been completed, by calling the or method, any further attempt to add MSIL is ignored. No exception is thrown. /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. - /// - /// /// /// How to: Define and Execute Dynamic Methods public ILGenerator GetILGenerator() @@ -907,8 +885,7 @@ public ILGenerator GetILGenerator() /// /// If this property is set to true, the emitted Microsoft intermediate language (MSIL) includes initialization of local variables. If it is set to false, local variables are not initialized and the generated code is unverifiable. /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. - /// - /// + /// /// public bool InitLocals { From 07b69b4ea929ec34a8720896577046b5078069b0 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 16:41:14 -0800 Subject: [PATCH 03/12] Rewrite DynamicMethod samples as runnable file-based app Each #region is a testable example with assertions. The app creates a DynamicMethod, exercises each documented property/method, and returns nonzero on failure. Run with: dotnet run DynamicMethod.Examples.cs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Reflection/Emit/DynamicMethod.Examples.cs | 318 +++++++----------- 1 file changed, 118 insertions(+), 200 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs index 449e84905fd941..e13940e913cbb2 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs @@ -1,210 +1,128 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// This file contains code examples for XML documentation. -// The examples are referenced by the DynamicMethod class documentation using #region names. +#:property PublishAot=false -#pragma warning disable CS8321 // Local function is declared but never used +// Runnable examples for DynamicMethod XML doc comments. +// Each #region is referenced by tags in DynamicMethod.cs. +// Run: dotnet run DynamicMethod.Examples.cs -using System; +using System.Globalization; using System.Reflection; using System.Reflection.Emit; -namespace System.Reflection.Emit.Examples +// Create a DynamicMethod shared by the property/method examples below. +DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); +int failures = 0; + +void Fail(string name, string message) { - internal static class DynamicMethodExamples - { - private static void Examples() - { - // Note: 'hello' represents a DynamicMethod instance used in the examples below - - #region Name - // Display the name specified when the dynamic method was created. - // Note that the name can be blank. - Console.WriteLine("\r\nName: {0}", hello.Name); - #endregion - - #region DeclaringType - // Display the declaring type, which is always null for dynamic - // methods. - if (hello.DeclaringType == null) - { - Console.WriteLine("\r\nDeclaringType is always null for dynamic methods."); - } - else - { - Console.WriteLine("DeclaringType: {0}", hello.DeclaringType); - } - #endregion - - #region ReflectedType - // For dynamic methods, the reflected type is always null. - if (hello.ReflectedType == null) - { - Console.WriteLine("\r\nReflectedType is null."); - } - else - { - Console.WriteLine("\r\nReflectedType: {0}", hello.ReflectedType); - } - #endregion - - #region Module - // Display the module specified when the dynamic method was created. - Console.WriteLine("\r\nModule: {0}", hello.Module); - #endregion - - #region Attributes - // Display MethodAttributes for the dynamic method, set when - // the dynamic method was created. - Console.WriteLine("\r\nMethod Attributes: {0}", hello.Attributes); - #endregion - - #region CallingConvention - // Display the calling convention of the dynamic method, set when the - // dynamic method was created. - Console.WriteLine("\r\nCalling convention: {0}", hello.CallingConvention); - #endregion - - #region GetParameters - // Display parameter information. - ParameterInfo[] parameters = hello.GetParameters(); - Console.WriteLine("\r\nParameters: name, type, ParameterAttributes"); - foreach (ParameterInfo p in parameters) - { - Console.WriteLine("\t{0}, {1}, {2}", - p.Name, p.ParameterType, p.Attributes); - } - #endregion - - #region ReturnType - // If the method has no return type, ReturnType is System.Void. - Console.WriteLine("\r\nReturn type: {0}", hello.ReturnType); - #endregion - - #region ReturnParameter - if (hello.ReturnParameter == null) - { - Console.WriteLine("\r\nMethod has no return parameter."); - } - else - { - Console.WriteLine("\r\nReturn parameter: {0}", hello.ReturnParameter); - } - #endregion - - #region ReturnTypeCustomAttributes - // ReturnTypeCustomAttributes returns an ICustomAttributeProvider - // that can be used to enumerate the custom attributes of the - // return value. At present, there is no way to set such custom - // attributes, so the list is empty. - if (hello.ReturnType == typeof(void)) - { - Console.WriteLine("The method has no return type."); - } - else - { - ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes; - object[] returnAttributes = caProvider.GetCustomAttributes(true); - if (returnAttributes.Length == 0) - { - Console.WriteLine("\r\nThe return type has no custom attributes."); - } - else - { - Console.WriteLine("\r\nThe return type has the following custom attributes:"); - foreach (object attr in returnAttributes) - { - Console.WriteLine("\t{0}", attr.ToString()); - } - } - } - #endregion - - #region DefineParameter - // Add parameter information to the dynamic method. (This is not - // necessary, but can be useful for debugging.) For each parameter, - // identified by position, supply the parameter attributes and a - // parameter name. - hello.DefineParameter(1, ParameterAttributes.In, "message"); - hello.DefineParameter(2, ParameterAttributes.In, "valueToReturn"); - #endregion - - #region ToString - Console.WriteLine("\r\nToString: {0}", hello.ToString()); - #endregion - - #region InitLocals - // Display the default value for InitLocals. - if (hello.InitLocals) - { - Console.Write("\r\nThis method contains verifiable code."); - } - else - { - Console.Write("\r\nThis method contains unverifiable code."); - } - Console.WriteLine(" (InitLocals = {0})", hello.InitLocals); - #endregion - - #region GetILGenerator - // Create an array that specifies the parameter types of the - // overload of Console.WriteLine to be used in Hello. - Type[] writeStringArgs = {typeof(string)}; - // Get the overload of Console.WriteLine that has one - // String parameter. - MethodInfo writeString = typeof(Console).GetMethod("WriteLine", - writeStringArgs); - - // Get an ILGenerator and emit a body for the dynamic method, - // using a stream size larger than the IL that will be - // emitted. - ILGenerator il = hello.GetILGenerator(256); - // Load the first argument, which is a string, onto the stack. - il.Emit(OpCodes.Ldarg_0); - // Call the overload of Console.WriteLine that prints a string. - il.EmitCall(OpCodes.Call, writeString, null); - // The Hello method returns the value of the second argument; - // to do this, load the onto the stack and return. - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ret); - #endregion - - #region CreateDelegate - // Create a delegate that represents the dynamic method. This - // action completes the method. Any further attempts to - // change the method are ignored. - HelloDelegate hi = - (HelloDelegate) hello.CreateDelegate(typeof(HelloDelegate)); - - // Use the delegate to execute the dynamic method. - Console.WriteLine("\r\nUse the delegate to execute the dynamic method:"); - int retval = hi("\r\nHello, World!", 42); - Console.WriteLine("Invoking delegate hi(\"Hello, World!\", 42) returned: " + retval); - - // Execute it again, with different arguments. - retval = hi("\r\nHi, Mom!", 5280); - Console.WriteLine("Invoking delegate hi(\"Hi, Mom!\", 5280) returned: " + retval); - #endregion - - #region Invoke - Console.WriteLine("\r\nUse the Invoke method to execute the dynamic method:"); - // Create an array of arguments to use with the Invoke method. - object[] invokeArgs = {"\r\nHello, World!", 42}; - // Invoke the dynamic method using the arguments. This is much - // slower than using the delegate, because you must create an - // array to contain the arguments, and value-type arguments - // must be boxed. - object objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new System.Globalization.CultureInfo("en-us")); - Console.WriteLine("hello.Invoke returned: " + objRet); - #endregion - } - - // Placeholder for the DynamicMethod variable used in examples - private static DynamicMethod hello = null!; - - // Declare a delegate type that can be used to execute the completed - // dynamic method. - private delegate int HelloDelegate(string msg, int ret); - } + Console.Error.WriteLine($"FAIL: {name} — {message}"); + failures++; } + +#region Name +// The name specified when the dynamic method was created. +Console.WriteLine($"Name: {hello.Name}"); +#endregion +if (hello.Name != "Hello") Fail("Name", $"Expected 'Hello', got '{hello.Name}'"); + +#region DeclaringType +// DeclaringType is always null for dynamic methods. +Console.WriteLine($"DeclaringType: {hello.DeclaringType?.ToString() ?? "(null)"}"); +#endregion +if (hello.DeclaringType is not null) Fail("DeclaringType", "Expected null"); + +#region ReflectedType +// ReflectedType is always null for dynamic methods. +Console.WriteLine($"ReflectedType: {hello.ReflectedType?.ToString() ?? "(null)"}"); +#endregion +if (hello.ReflectedType is not null) Fail("ReflectedType", "Expected null"); + +#region Module +// The module the dynamic method is associated with. +Console.WriteLine($"Module: {hello.Module}"); +#endregion +if (hello.Module != typeof(string).Module) Fail("Module", "Expected System.Private.CoreLib module"); + +#region Attributes +// Dynamic methods always have Public | Static attributes. +Console.WriteLine($"Attributes: {hello.Attributes}"); +#endregion +if (hello.Attributes != (MethodAttributes.Public | MethodAttributes.Static)) + Fail("Attributes", $"Expected Public | Static, got {hello.Attributes}"); + +#region CallingConvention +// Dynamic methods always use Standard calling convention. +Console.WriteLine($"CallingConvention: {hello.CallingConvention}"); +#endregion +if (hello.CallingConvention != CallingConventions.Standard) + Fail("CallingConvention", $"Expected Standard, got {hello.CallingConvention}"); + +#region InitLocals +// InitLocals defaults to true — local variables are zero-initialized. +Console.WriteLine($"InitLocals: {hello.InitLocals}"); +#endregion +if (!hello.InitLocals) Fail("InitLocals", "Expected true"); + +#region ReturnType +// The return type specified when the dynamic method was created. +Console.WriteLine($"ReturnType: {hello.ReturnType}"); +#endregion +if (hello.ReturnType != typeof(int)) Fail("ReturnType", $"Expected Int32, got {hello.ReturnType}"); + +#region ReturnTypeCustomAttributes +// At present there is no way to set custom attributes on the return type, +// so the list is always empty. +ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes; +object[] returnAttributes = caProvider.GetCustomAttributes(true); +Console.WriteLine($"Return type custom attributes: {returnAttributes.Length}"); +#endregion +if (returnAttributes.Length != 0) Fail("ReturnTypeCustomAttributes", "Expected 0 attributes"); + +#region DefineParameter +// Optionally add parameter metadata (useful for debugging). +hello.DefineParameter(1, ParameterAttributes.In, "message"); +hello.DefineParameter(2, ParameterAttributes.In, "valueToReturn"); +#endregion + +#region GetParameters +// Retrieve parameter info after calling DefineParameter. +ParameterInfo[] parameters = hello.GetParameters(); +foreach (ParameterInfo p in parameters) + Console.WriteLine($" Param: {p.Name}, {p.ParameterType}, {p.Attributes}"); +#endregion +if (parameters.Length != 2) Fail("GetParameters", $"Expected 2 parameters, got {parameters.Length}"); + +#region ToString +// ToString returns the signature: return type, name, and parameter types. +string sig = hello.ToString(); +Console.WriteLine($"ToString: {sig}"); +#endregion +if (!sig.Contains("Hello")) Fail("ToString", $"Expected signature to contain 'Hello'"); + +// Emit a method body so we can test CreateDelegate and Invoke. +MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!; +ILGenerator il = hello.GetILGenerator(); +il.Emit(OpCodes.Ldarg_0); +il.EmitCall(OpCodes.Call, writeString, null); +il.Emit(OpCodes.Ldarg_1); +il.Emit(OpCodes.Ret); + +// Complete the method and execute it via delegate and reflection. +Func hi = hello.CreateDelegate>(); +int retval = hi("Hello from delegate!", 42); +if (retval != 42) Fail("CreateDelegate", $"Expected 42, got {retval}"); + +object? objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, + ["Hello from Invoke!", 99], CultureInfo.InvariantCulture); +if (objRet is not 99) Fail("Invoke", $"Expected 99, got {objRet}"); + +if (failures > 0) +{ + Console.Error.WriteLine($"\n{failures} example(s) failed."); + return 1; +} + +Console.WriteLine("\nAll examples passed."); +return 0; From de654f6b769040c870e5c9b6ef18fb35dbf32b97 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 16:59:56 -0800 Subject: [PATCH 04/12] Add Overview and CtorOwnerType samples, restore code links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create two additional file-based app samples for the full-program examples that were missing code references: - DynamicMethod.Overview.cs: ctor + emit + delegate + Invoke - DynamicMethod.CtorOwnerType.cs: ctor with owner type, private field access, bound delegate Restore references in DynamicMethod.cs for the type-level example, constructor with Module, constructor with owner Type, and GetILGenerator — all now pointing to local sample files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Emit/DynamicMethod.CtorOwnerType.cs | 60 +++++++++++++++++++ .../Reflection/Emit/DynamicMethod.Overview.cs | 45 ++++++++++++++ .../System/Reflection/Emit/DynamicMethod.cs | 7 +++ 3 files changed, 112 insertions(+) create mode 100644 src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs create mode 100644 src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs new file mode 100644 index 00000000000000..b2dbf42bf11fef --- /dev/null +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#:property PublishAot=false + +// Example: Create a DynamicMethod with an owner type to access private members. +// Shows CreateDelegate with a bound instance (instance-style invocation). +// Run: dotnet run DynamicMethod.CtorOwnerType.cs + +using System.Reflection; +using System.Reflection.Emit; + +#region Snippet1 +// A DynamicMethod associated with a type can access its private members. +DynamicMethod changeID = new( + "", typeof(int), [typeof(Example), typeof(int)], typeof(Example)); + +// Get a FieldInfo for the private field 'id'. +FieldInfo fid = typeof(Example).GetField("id", BindingFlags.NonPublic | BindingFlags.Instance)!; + +ILGenerator ilg = changeID.GetILGenerator(); +// Push current value of 'id' onto the stack. +ilg.Emit(OpCodes.Ldarg_0); +ilg.Emit(OpCodes.Ldfld, fid); +// Store the new value. +ilg.Emit(OpCodes.Ldarg_0); +ilg.Emit(OpCodes.Ldarg_1); +ilg.Emit(OpCodes.Stfld, fid); +// Return the old value. +ilg.Emit(OpCodes.Ret); + +// Static-style delegate: takes (Example, int), returns old id. +var setId = changeID.CreateDelegate>(); + +Example ex = new(42); +int oldId = setId(ex, 1492); +Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}"); + +// Instance-style delegate: bind to a specific Example instance. +var setBound = (Func)changeID.CreateDelegate(typeof(Func), ex); +oldId = setBound(2700); +Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}"); +#endregion + +// Verify +if (ex.ID != 2700) +{ + Console.Error.WriteLine($"FAIL: expected 2700, got {ex.ID}"); + return 1; +} + +Console.WriteLine("Passed."); +return 0; + +// Helper types +public class Example(int id) +{ + private int id = id; + public int ID => id; +} diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs new file mode 100644 index 00000000000000..f72ab471285eed --- /dev/null +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#:property PublishAot=false + +// Example: Create a DynamicMethod, emit IL, and execute via delegate and Invoke. +// Referenced by DynamicMethod class overview and GetILGenerator/constructor docs. +// Run: dotnet run DynamicMethod.Overview.cs + +using System.Reflection; +using System.Reflection.Emit; + +#region Snippet1 +// Create a dynamic method with return type int and two parameters (string, int). +DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); + +// Emit a body: print the string argument, then return the int argument. +MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!; +ILGenerator il = hello.GetILGenerator(); +il.Emit(OpCodes.Ldarg_0); +il.EmitCall(OpCodes.Call, writeString, null); +il.Emit(OpCodes.Ldarg_1); +il.Emit(OpCodes.Ret); + +// Create a delegate that represents the dynamic method. +Func hi = hello.CreateDelegate>(); + +// Execute via delegate. +int retval = hi("Hello, World!", 42); +Console.WriteLine($"Delegate returned: {retval}"); + +// Execute via Invoke (slower — requires boxing and array allocation). +object? objRet = hello.Invoke(null, ["Hello via Invoke!", 99]); +Console.WriteLine($"Invoke returned: {objRet}"); +#endregion + +// Verify results +if (retval != 42 || objRet is not 99) +{ + Console.Error.WriteLine("FAIL: unexpected return values"); + return 1; +} + +Console.WriteLine("Passed."); +return 0; diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index 3b15f39103252d..004c5ccd8c6d73 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -16,6 +16,10 @@ namespace System.Reflection.Emit /// /// For more information about this API, see Supplemental API remarks for DynamicMethod. /// + /// + /// The following example creates a dynamic method, emits a method body, and executes it via a delegate and via . + /// + /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit /// Walkthrough: Emitting Code in Partial Trust Scenarios @@ -135,6 +139,7 @@ public DynamicMethod(string name, /// The dynamic method created with this constructor has access to public and internal (Friend in Visual Basic) members of all the types contained in module m. /// > For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: m is a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -268,6 +273,7 @@ public DynamicMethod(string name, /// The example code then creates a that changes the private field of an instance of Example and returns the previous value. /// The example code creates an instance of Example and then creates two delegates. The first is of type UseLikeStatic, which has the same parameters as the dynamic method. The second is of type UseLikeInstance, which lacks the first parameter (of type Example). This delegate is created using the method overload; the second parameter of that method overload is an instance of Example, in this case the instance just created, which is bound to the newly created delegate. Whenever that delegate is invoked, the dynamic method acts on the bound instance of Example. /// The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromExample, and the delegate calls are repeated. + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -871,6 +877,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// /// After a dynamic method has been completed, by calling the or method, any further attempt to add MSIL is ignored. No exception is thrown. /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. + /// /// /// How to: Define and Execute Dynamic Methods public ILGenerator GetILGenerator() From 9ce8b3c76085a32daae85314d003fef622e594d8 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 17:08:08 -0800 Subject: [PATCH 05/12] Add samples.json for DocId-to-sample mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Place samples.json at the samples directory root as the stable contract between sample authoring and the migration tool. The tool reads this to generate tags — no manual editing of source file references needed. Keys are DocId strings (T:, M:, P:), values are {file, region}. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../samples/samples.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/libraries/System.Private.CoreLib/samples/samples.json diff --git a/src/libraries/System.Private.CoreLib/samples/samples.json b/src/libraries/System.Private.CoreLib/samples/samples.json new file mode 100644 index 00000000000000..ac68ebbe1b1d30 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/samples/samples.json @@ -0,0 +1,18 @@ +{ + "T:System.Reflection.Emit.DynamicMethod": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1" }, + "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Reflection.Module)": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1" }, + "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Type)": { "file": "DynamicMethod.CtorOwnerType.cs", "region": "Snippet1" }, + "P:System.Reflection.Emit.DynamicMethod.Name": { "file": "DynamicMethod.Examples.cs", "region": "Name" }, + "P:System.Reflection.Emit.DynamicMethod.DeclaringType": { "file": "DynamicMethod.Examples.cs", "region": "DeclaringType" }, + "P:System.Reflection.Emit.DynamicMethod.ReflectedType": { "file": "DynamicMethod.Examples.cs", "region": "ReflectedType" }, + "P:System.Reflection.Emit.DynamicMethod.Module": { "file": "DynamicMethod.Examples.cs", "region": "Module" }, + "P:System.Reflection.Emit.DynamicMethod.Attributes": { "file": "DynamicMethod.Examples.cs", "region": "Attributes" }, + "P:System.Reflection.Emit.DynamicMethod.CallingConvention": { "file": "DynamicMethod.Examples.cs", "region": "CallingConvention" }, + "P:System.Reflection.Emit.DynamicMethod.ReturnType": { "file": "DynamicMethod.Examples.cs", "region": "ReturnType" }, + "P:System.Reflection.Emit.DynamicMethod.ReturnTypeCustomAttributes": { "file": "DynamicMethod.Examples.cs", "region": "ReturnTypeCustomAttributes" }, + "P:System.Reflection.Emit.DynamicMethod.InitLocals": { "file": "DynamicMethod.Examples.cs", "region": "InitLocals" }, + "M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "DynamicMethod.Examples.cs", "region": "ToString" }, + "M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "DynamicMethod.Examples.cs", "region": "GetParameters" }, + "M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "DynamicMethod.Examples.cs", "region": "DefineParameter" }, + "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1" } +} From f026749f69ed058ffaaae71422339938d65b1cd1 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 17:28:23 -0800 Subject: [PATCH 06/12] Add titles to samples.json entries Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../samples/samples.json | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/samples/samples.json b/src/libraries/System.Private.CoreLib/samples/samples.json index ac68ebbe1b1d30..f086f86a626a89 100644 --- a/src/libraries/System.Private.CoreLib/samples/samples.json +++ b/src/libraries/System.Private.CoreLib/samples/samples.json @@ -1,18 +1,18 @@ { - "T:System.Reflection.Emit.DynamicMethod": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1" }, - "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Reflection.Module)": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1" }, - "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Type)": { "file": "DynamicMethod.CtorOwnerType.cs", "region": "Snippet1" }, - "P:System.Reflection.Emit.DynamicMethod.Name": { "file": "DynamicMethod.Examples.cs", "region": "Name" }, - "P:System.Reflection.Emit.DynamicMethod.DeclaringType": { "file": "DynamicMethod.Examples.cs", "region": "DeclaringType" }, - "P:System.Reflection.Emit.DynamicMethod.ReflectedType": { "file": "DynamicMethod.Examples.cs", "region": "ReflectedType" }, - "P:System.Reflection.Emit.DynamicMethod.Module": { "file": "DynamicMethod.Examples.cs", "region": "Module" }, - "P:System.Reflection.Emit.DynamicMethod.Attributes": { "file": "DynamicMethod.Examples.cs", "region": "Attributes" }, - "P:System.Reflection.Emit.DynamicMethod.CallingConvention": { "file": "DynamicMethod.Examples.cs", "region": "CallingConvention" }, - "P:System.Reflection.Emit.DynamicMethod.ReturnType": { "file": "DynamicMethod.Examples.cs", "region": "ReturnType" }, - "P:System.Reflection.Emit.DynamicMethod.ReturnTypeCustomAttributes": { "file": "DynamicMethod.Examples.cs", "region": "ReturnTypeCustomAttributes" }, - "P:System.Reflection.Emit.DynamicMethod.InitLocals": { "file": "DynamicMethod.Examples.cs", "region": "InitLocals" }, - "M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "DynamicMethod.Examples.cs", "region": "ToString" }, - "M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "DynamicMethod.Examples.cs", "region": "GetParameters" }, - "M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "DynamicMethod.Examples.cs", "region": "DefineParameter" }, - "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1" } + "T:System.Reflection.Emit.DynamicMethod": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1", "title": "Creating and invoking a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Reflection.Module)": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1", "title": "Creating a DynamicMethod associated with a module" }, + "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Type)": { "file": "DynamicMethod.CtorOwnerType.cs", "region": "Snippet1", "title": "Creating a DynamicMethod with an owner type" }, + "P:System.Reflection.Emit.DynamicMethod.Name": { "file": "DynamicMethod.Examples.cs", "region": "Name", "title": "Getting the name of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.DeclaringType": { "file": "DynamicMethod.Examples.cs", "region": "DeclaringType", "title": "Getting the declaring type of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.ReflectedType": { "file": "DynamicMethod.Examples.cs", "region": "ReflectedType", "title": "Getting the reflected type of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.Module": { "file": "DynamicMethod.Examples.cs", "region": "Module", "title": "Getting the module of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.Attributes": { "file": "DynamicMethod.Examples.cs", "region": "Attributes", "title": "Getting the attributes of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.CallingConvention": { "file": "DynamicMethod.Examples.cs", "region": "CallingConvention", "title": "Getting the calling convention of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.ReturnType": { "file": "DynamicMethod.Examples.cs", "region": "ReturnType", "title": "Getting the return type of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.ReturnTypeCustomAttributes": { "file": "DynamicMethod.Examples.cs", "region": "ReturnTypeCustomAttributes", "title": "Getting return type custom attributes" }, + "P:System.Reflection.Emit.DynamicMethod.InitLocals": { "file": "DynamicMethod.Examples.cs", "region": "InitLocals", "title": "Checking InitLocals on a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "DynamicMethod.Examples.cs", "region": "ToString", "title": "Getting the string representation of a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "DynamicMethod.Examples.cs", "region": "GetParameters", "title": "Getting parameter info from a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "DynamicMethod.Examples.cs", "region": "DefineParameter", "title": "Defining parameters on a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1", "title": "Getting the IL generator for a DynamicMethod" } } From a3b3f28fd63a379ca4d56a4d8478e28a56da09fb Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 17:37:23 -0800 Subject: [PATCH 07/12] Regenerate DynamicMethod code tags via merge tool with samples.json All 16 sample references now injected by the slash merge --samples pipeline, with titles and correct relative paths. Paths changed from samples/System/Reflection/Emit/DynamicMethod.*.cs to samples/DynamicMethod.*.cs to match samples.json file entries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../System/Reflection/Emit/DynamicMethod.cs | 64 ++++++++++++++----- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index 004c5ccd8c6d73..200fbe581a680b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -18,7 +18,9 @@ namespace System.Reflection.Emit /// /// /// The following example creates a dynamic method, emits a method body, and executes it via a delegate and via . - /// + /// + /// + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -139,8 +141,10 @@ public DynamicMethod(string name, /// The dynamic method created with this constructor has access to public and internal (Friend in Visual Basic) members of all the types contained in module m. /// > For backward compatibility, this constructor demands with the ControlEvidence flag if the following conditions are both true: m is a module other than the calling module, and the demand for with the MemberAccess flag has failed. If the demand for succeeds, the operation is allowed. /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. - /// /// + /// + /// + /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] @@ -273,8 +277,10 @@ public DynamicMethod(string name, /// The example code then creates a that changes the private field of an instance of Example and returns the previous value. /// The example code creates an instance of Example and then creates two delegates. The first is of type UseLikeStatic, which has the same parameters as the dynamic method. The second is of type UseLikeInstance, which lacks the first parameter (of type Example). This delegate is created using the method overload; the second parameter of that method overload is an instance of Example, in this case the instance just created, which is bound to the newly created delegate. Whenever that delegate is invoked, the dynamic method acts on the bound instance of Example. /// The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromExample, and the delegate calls are repeated. - /// /// + /// + /// + /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit [RequiresDynamicCode("Creating a DynamicMethod requires dynamic code.")] @@ -504,8 +510,10 @@ private void Init(string name, /// /// The signature includes only types and the method name, if any. Parameter names are not included. /// The following code example displays the method of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override string ToString() { var sbName = new ValueStringBuilder(MethodNameBufferSize); @@ -530,8 +538,10 @@ public override string ToString() /// It is not necessary to name dynamic methods. /// /// The following code example displays the name of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override string Name => _name; /// @@ -541,8 +551,10 @@ public override string ToString() /// /// This property always returns null for dynamic methods. Even when a dynamic method is logically associated with a type, it is not declared by the type. /// The following code example displays the declaring type of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override Type? DeclaringType => null; /// @@ -552,8 +564,10 @@ public override string ToString() /// /// This property always returns null for dynamic methods. /// The following code example displays the reflected type of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override Type? ReflectedType => null; /// @@ -563,8 +577,10 @@ public override string ToString() /// /// If a module was specified when the dynamic method was created, this property returns that module. If a type was specified as the owner when the dynamic method was created, this property returns the module that contains that type. /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override Module Module => _module; // we cannot return a MethodHandle because we cannot track it via GC so this method is off limits @@ -582,8 +598,10 @@ public override string ToString() /// /// Currently, the method attributes for a dynamic method are always and . /// The following code example displays the method attributes of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override MethodAttributes Attributes => _attributes; /// @@ -593,8 +611,10 @@ public override string ToString() /// /// Currently, the calling convention for a dynamic method is always . /// The following code example displays the calling convention of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override CallingConventions CallingConvention => _callingConvention; /// @@ -613,8 +633,10 @@ public override string ToString() /// /// The objects returned by this method are for information only. Use the method to set or change the characteristics of the parameters. /// The following code example displays the parameters of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override ParameterInfo[] GetParameters() => GetParametersAsSpan().ToArray(); @@ -810,8 +832,10 @@ public override bool IsDefined(Type attributeType, bool inherit) /// /// If null was specified for the return type when the dynamic method was created, this property returns Void. /// The following code example displays the return type of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override Type ReturnType => _returnType; /// @@ -830,8 +854,10 @@ public override bool IsDefined(Type attributeType, bool inherit) /// /// Custom attributes are not supported on the return type of a dynamic method, so the array of custom attributes returned by the method is always empty. /// The following code example shows how to display the custom attributes of the return type of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public override ICustomAttributeProvider ReturnTypeCustomAttributes => new EmptyCAHolder(); // @@ -850,8 +876,10 @@ public override bool IsDefined(Type attributeType, bool inherit) /// If position is 0, the method refers to the return value. Setting parameter information has no effect on the return value. /// If the dynamic method has already been completed, by calling the or method, the method has no effect. No exception is thrown. /// The following code example shows how to define parameter information for a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public ParameterBuilder? DefineParameter(int position, ParameterAttributes attributes, string? parameterName) { if (position < 0 || position > _parameterTypes.Length) @@ -877,8 +905,10 @@ public override bool IsDefined(Type attributeType, bool inherit) /// /// After a dynamic method has been completed, by calling the or method, any further attempt to add MSIL is ignored. No exception is thrown. /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. - /// /// + /// + /// + /// /// How to: Define and Execute Dynamic Methods public ILGenerator GetILGenerator() { @@ -892,8 +922,10 @@ public ILGenerator GetILGenerator() /// /// If this property is set to true, the emitted Microsoft intermediate language (MSIL) includes initialization of local variables. If it is set to false, local variables are not initialized and the generated code is unverifiable. /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. - /// /// + /// + /// + /// public bool InitLocals { get => _initLocals; From 18957d69bb172cd78432c00805dc0351b52e031e Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 17:38:36 -0800 Subject: [PATCH 08/12] Rename sample regions and fix paths in samples.json - Snippet1 -> CreateAndInvoke (Overview), OwnerTypeAccess (CtorOwnerType) - Fix file paths to include System/Reflection/Emit/ subdirectory - Regenerate DynamicMethod.cs code tags via merge tool Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Emit/DynamicMethod.CtorOwnerType.cs | 4 +- .../Reflection/Emit/DynamicMethod.Overview.cs | 4 +- .../samples/samples.json | 32 +++++----- .../System/Reflection/Emit/DynamicMethod.cs | 64 ++++++++++++++----- 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs index b2dbf42bf11fef..bff904234169e3 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs @@ -10,7 +10,7 @@ using System.Reflection; using System.Reflection.Emit; -#region Snippet1 +#region OwnerTypeAccess // A DynamicMethod associated with a type can access its private members. DynamicMethod changeID = new( "", typeof(int), [typeof(Example), typeof(int)], typeof(Example)); @@ -40,7 +40,7 @@ var setBound = (Func)changeID.CreateDelegate(typeof(Func), ex); oldId = setBound(2700); Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}"); -#endregion +#endregion OwnerTypeAccess // Verify if (ex.ID != 2700) diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs index f72ab471285eed..1ab18089170922 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs @@ -10,7 +10,7 @@ using System.Reflection; using System.Reflection.Emit; -#region Snippet1 +#region CreateAndInvoke // Create a dynamic method with return type int and two parameters (string, int). DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); @@ -32,7 +32,7 @@ // Execute via Invoke (slower — requires boxing and array allocation). object? objRet = hello.Invoke(null, ["Hello via Invoke!", 99]); Console.WriteLine($"Invoke returned: {objRet}"); -#endregion +#endregion CreateAndInvoke // Verify results if (retval != 42 || objRet is not 99) diff --git a/src/libraries/System.Private.CoreLib/samples/samples.json b/src/libraries/System.Private.CoreLib/samples/samples.json index f086f86a626a89..5939160ef5a9dc 100644 --- a/src/libraries/System.Private.CoreLib/samples/samples.json +++ b/src/libraries/System.Private.CoreLib/samples/samples.json @@ -1,18 +1,18 @@ { - "T:System.Reflection.Emit.DynamicMethod": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1", "title": "Creating and invoking a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Reflection.Module)": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1", "title": "Creating a DynamicMethod associated with a module" }, - "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Type)": { "file": "DynamicMethod.CtorOwnerType.cs", "region": "Snippet1", "title": "Creating a DynamicMethod with an owner type" }, - "P:System.Reflection.Emit.DynamicMethod.Name": { "file": "DynamicMethod.Examples.cs", "region": "Name", "title": "Getting the name of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.DeclaringType": { "file": "DynamicMethod.Examples.cs", "region": "DeclaringType", "title": "Getting the declaring type of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.ReflectedType": { "file": "DynamicMethod.Examples.cs", "region": "ReflectedType", "title": "Getting the reflected type of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.Module": { "file": "DynamicMethod.Examples.cs", "region": "Module", "title": "Getting the module of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.Attributes": { "file": "DynamicMethod.Examples.cs", "region": "Attributes", "title": "Getting the attributes of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.CallingConvention": { "file": "DynamicMethod.Examples.cs", "region": "CallingConvention", "title": "Getting the calling convention of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.ReturnType": { "file": "DynamicMethod.Examples.cs", "region": "ReturnType", "title": "Getting the return type of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.ReturnTypeCustomAttributes": { "file": "DynamicMethod.Examples.cs", "region": "ReturnTypeCustomAttributes", "title": "Getting return type custom attributes" }, - "P:System.Reflection.Emit.DynamicMethod.InitLocals": { "file": "DynamicMethod.Examples.cs", "region": "InitLocals", "title": "Checking InitLocals on a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "DynamicMethod.Examples.cs", "region": "ToString", "title": "Getting the string representation of a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "DynamicMethod.Examples.cs", "region": "GetParameters", "title": "Getting parameter info from a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "DynamicMethod.Examples.cs", "region": "DefineParameter", "title": "Defining parameters on a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "DynamicMethod.Overview.cs", "region": "Snippet1", "title": "Getting the IL generator for a DynamicMethod" } + "T:System.Reflection.Emit.DynamicMethod": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "region": "CreateAndInvoke", "title": "Creating and invoking a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Reflection.Module)": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "region": "CreateAndInvoke", "title": "Creating a DynamicMethod associated with a module" }, + "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Type)": { "file": "System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs", "region": "OwnerTypeAccess", "title": "Creating a DynamicMethod with an owner type" }, + "P:System.Reflection.Emit.DynamicMethod.Name": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "Name", "title": "Getting the name of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.DeclaringType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "DeclaringType", "title": "Getting the declaring type of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.ReflectedType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ReflectedType", "title": "Getting the reflected type of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.Module": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "Module", "title": "Getting the module of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.Attributes": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "Attributes", "title": "Getting the attributes of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.CallingConvention": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "CallingConvention", "title": "Getting the calling convention of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.ReturnType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ReturnType", "title": "Getting the return type of a DynamicMethod" }, + "P:System.Reflection.Emit.DynamicMethod.ReturnTypeCustomAttributes": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ReturnTypeCustomAttributes", "title": "Getting return type custom attributes" }, + "P:System.Reflection.Emit.DynamicMethod.InitLocals": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "InitLocals", "title": "Checking InitLocals on a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ToString", "title": "Getting the string representation of a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "GetParameters", "title": "Getting parameter info from a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "DefineParameter", "title": "Defining parameters on a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "region": "CreateAndInvoke", "title": "Getting the IL generator for a DynamicMethod" } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index 200fbe581a680b..7c63042b96e788 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -20,7 +20,9 @@ namespace System.Reflection.Emit /// The following example creates a dynamic method, emits a method body, and executes it via a delegate and via . /// /// - /// + /// + /// + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -143,7 +145,9 @@ public DynamicMethod(string name, /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. /// /// - /// + /// + /// + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -279,7 +283,9 @@ public DynamicMethod(string name, /// The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromExample, and the delegate calls are repeated. /// /// - /// + /// + /// + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -512,7 +518,9 @@ private void Init(string name, /// The following code example displays the method of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override string ToString() { @@ -540,7 +548,9 @@ public override string ToString() /// The following code example displays the name of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override string Name => _name; @@ -553,7 +563,9 @@ public override string ToString() /// The following code example displays the declaring type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override Type? DeclaringType => null; @@ -566,7 +578,9 @@ public override string ToString() /// The following code example displays the reflected type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override Type? ReflectedType => null; @@ -579,7 +593,9 @@ public override string ToString() /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override Module Module => _module; @@ -600,7 +616,9 @@ public override string ToString() /// The following code example displays the method attributes of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override MethodAttributes Attributes => _attributes; @@ -613,7 +631,9 @@ public override string ToString() /// The following code example displays the calling convention of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override CallingConventions CallingConvention => _callingConvention; @@ -635,7 +655,9 @@ public override string ToString() /// The following code example displays the parameters of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override ParameterInfo[] GetParameters() => GetParametersAsSpan().ToArray(); @@ -834,7 +856,9 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example displays the return type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override Type ReturnType => _returnType; @@ -856,7 +880,9 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example shows how to display the custom attributes of the return type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public override ICustomAttributeProvider ReturnTypeCustomAttributes => new EmptyCAHolder(); @@ -878,7 +904,9 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example shows how to define parameter information for a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public ParameterBuilder? DefineParameter(int position, ParameterAttributes attributes, string? parameterName) { @@ -907,7 +935,9 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. /// /// - /// + /// + /// + /// /// /// How to: Define and Execute Dynamic Methods public ILGenerator GetILGenerator() @@ -924,7 +954,9 @@ public ILGenerator GetILGenerator() /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// + /// + /// /// public bool InitLocals { From 742244170cc2a2c2101349169c0ae77c6cc56ef5 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 17:52:26 -0800 Subject: [PATCH 09/12] =?UTF-8?q?Regenerate=20DynamicMethod.cs=20=E2=80=94?= =?UTF-8?q?=20clean=20example=20blocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../System/Reflection/Emit/DynamicMethod.cs | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index 7c63042b96e788..0de803d502e34c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -18,10 +18,6 @@ namespace System.Reflection.Emit /// /// /// The following example creates a dynamic method, emits a method body, and executes it via a delegate and via . - /// - /// - /// - /// /// /// /// How to: Define and Execute Dynamic Methods @@ -145,8 +141,6 @@ public DynamicMethod(string name, /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. /// /// - /// - /// /// /// /// How to: Define and Execute Dynamic Methods @@ -283,8 +277,6 @@ public DynamicMethod(string name, /// The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromExample, and the delegate calls are repeated. /// /// - /// - /// /// /// /// How to: Define and Execute Dynamic Methods @@ -518,8 +510,6 @@ private void Init(string name, /// The following code example displays the method of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override string ToString() @@ -548,8 +538,6 @@ public override string ToString() /// The following code example displays the name of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override string Name => _name; @@ -563,8 +551,6 @@ public override string ToString() /// The following code example displays the declaring type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override Type? DeclaringType => null; @@ -578,8 +564,6 @@ public override string ToString() /// The following code example displays the reflected type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override Type? ReflectedType => null; @@ -593,8 +577,6 @@ public override string ToString() /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override Module Module => _module; @@ -616,8 +598,6 @@ public override string ToString() /// The following code example displays the method attributes of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override MethodAttributes Attributes => _attributes; @@ -631,8 +611,6 @@ public override string ToString() /// The following code example displays the calling convention of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override CallingConventions CallingConvention => _callingConvention; @@ -655,8 +633,6 @@ public override string ToString() /// The following code example displays the parameters of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override ParameterInfo[] GetParameters() => @@ -856,8 +832,6 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example displays the return type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override Type ReturnType => _returnType; @@ -880,8 +854,6 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example shows how to display the custom attributes of the return type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public override ICustomAttributeProvider ReturnTypeCustomAttributes => new EmptyCAHolder(); @@ -904,8 +876,6 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example shows how to define parameter information for a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public ParameterBuilder? DefineParameter(int position, ParameterAttributes attributes, string? parameterName) @@ -935,8 +905,6 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. /// /// - /// - /// /// /// /// How to: Define and Execute Dynamic Methods @@ -954,8 +922,6 @@ public ILGenerator GetILGenerator() /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// - /// /// /// public bool InitLocals From 46cfb97e7f4a9c41705b17377d43ebb561f22733 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 21:05:01 -0800 Subject: [PATCH 10/12] Add Directory.Build.props/targets for runnable samples Blocks inheritance of repo-wide settings (IsAotCompatible, TreatWarningsAsErrors, resource targets) that prevent file-based app samples from building and running. Sets TargetFramework to net11.0 to match the SDK and PublishAot=false since DynamicMethod requires JIT. Removes per-file #:property PublishAot=false directives. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../samples/Directory.Build.props | 11 +++++++++++ .../samples/Directory.Build.targets | 2 ++ .../Reflection/Emit/DynamicMethod.CtorOwnerType.cs | 3 --- .../System/Reflection/Emit/DynamicMethod.Examples.cs | 3 --- .../System/Reflection/Emit/DynamicMethod.Overview.cs | 3 --- 5 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 src/libraries/System.Private.CoreLib/samples/Directory.Build.props create mode 100644 src/libraries/System.Private.CoreLib/samples/Directory.Build.targets diff --git a/src/libraries/System.Private.CoreLib/samples/Directory.Build.props b/src/libraries/System.Private.CoreLib/samples/Directory.Build.props new file mode 100644 index 00000000000000..d541fc3a2c6e17 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/samples/Directory.Build.props @@ -0,0 +1,11 @@ + + + + net11.0 + false + false + false + false + false + + diff --git a/src/libraries/System.Private.CoreLib/samples/Directory.Build.targets b/src/libraries/System.Private.CoreLib/samples/Directory.Build.targets new file mode 100644 index 00000000000000..8c119d5413b585 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/samples/Directory.Build.targets @@ -0,0 +1,2 @@ + + diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs index bff904234169e3..e328eafe12bc33 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs @@ -1,8 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. - -#:property PublishAot=false - // Example: Create a DynamicMethod with an owner type to access private members. // Shows CreateDelegate with a bound instance (instance-style invocation). // Run: dotnet run DynamicMethod.CtorOwnerType.cs diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs index e13940e913cbb2..1564cf1c3adcae 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs @@ -1,8 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. - -#:property PublishAot=false - // Runnable examples for DynamicMethod XML doc comments. // Each #region is referenced by tags in DynamicMethod.cs. // Run: dotnet run DynamicMethod.Examples.cs diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs index 1ab18089170922..278cb25601d1a6 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs @@ -1,8 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. - -#:property PublishAot=false - // Example: Create a DynamicMethod, emit IL, and execute via delegate and Invoke. // Referenced by DynamicMethod class overview and GetILGenerator/constructor docs. // Run: dotnet run DynamicMethod.Overview.cs From 8a8f318e795500862767bb38358738b281175cde Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Fri, 13 Feb 2026 21:30:38 -0800 Subject: [PATCH 11/12] Add CreateDelegate, Invoke, and GetILGenerator samples Add dedicated #region blocks for GetILGenerator, CreateDelegate, and Invoke in DynamicMethod.Examples.cs. Add samples.json entries for CreateDelegate(Type), CreateDelegate(Type,Object), Invoke, GetILGenerator, and GetILGenerator(int). The CreateDelegate/Invoke/ GetILGenerator(int) entries target the CoreCLR partial file. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Reflection/Emit/DynamicMethod.Examples.cs | 13 ++++++++++++- .../System.Private.CoreLib/samples/samples.json | 6 +++++- .../src/System/Reflection/Emit/DynamicMethod.cs | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs index 1564cf1c3adcae..403ca053059c49 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs @@ -100,19 +100,30 @@ void Fail(string name, string message) // Emit a method body so we can test CreateDelegate and Invoke. MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!; + +#region GetILGenerator +// Get an ILGenerator to emit the method body. ILGenerator il = hello.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.EmitCall(OpCodes.Call, writeString, null); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ret); +#endregion -// Complete the method and execute it via delegate and reflection. +#region CreateDelegate +// Create a strongly-typed delegate for the dynamic method. Func hi = hello.CreateDelegate>(); int retval = hi("Hello from delegate!", 42); +Console.WriteLine($"Delegate returned: {retval}"); +#endregion if (retval != 42) Fail("CreateDelegate", $"Expected 42, got {retval}"); +#region Invoke +// Invoke the dynamic method via reflection (slower than a delegate). object? objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, ["Hello from Invoke!", 99], CultureInfo.InvariantCulture); +Console.WriteLine($"Invoke returned: {objRet}"); +#endregion if (objRet is not 99) Fail("Invoke", $"Expected 99, got {objRet}"); if (failures > 0) diff --git a/src/libraries/System.Private.CoreLib/samples/samples.json b/src/libraries/System.Private.CoreLib/samples/samples.json index 5939160ef5a9dc..32e75747b5fa52 100644 --- a/src/libraries/System.Private.CoreLib/samples/samples.json +++ b/src/libraries/System.Private.CoreLib/samples/samples.json @@ -14,5 +14,9 @@ "M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ToString", "title": "Getting the string representation of a DynamicMethod" }, "M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "GetParameters", "title": "Getting parameter info from a DynamicMethod" }, "M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "DefineParameter", "title": "Defining parameters on a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "region": "CreateAndInvoke", "title": "Getting the IL generator for a DynamicMethod" } + "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "GetILGenerator", "title": "Getting the IL generator for a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.GetILGenerator(System.Int32)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "GetILGenerator", "title": "Getting the IL generator for a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "CreateDelegate", "title": "Creating a delegate from a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type,System.Object)": { "file": "System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs", "region": "OwnerTypeAccess", "title": "Creating a bound delegate from a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.Invoke(System.Object,System.Reflection.BindingFlags,System.Reflection.Binder,System.Object[],System.Globalization.CultureInfo)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "Invoke", "title": "Invoking a DynamicMethod via reflection" } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index 0de803d502e34c..c6b1e523cd193c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -905,7 +905,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. /// /// - /// + /// /// /// How to: Define and Execute Dynamic Methods public ILGenerator GetILGenerator() From 22a88a68a51046590ded92e586e6e3cf573dac07 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Sat, 14 Feb 2026 00:06:18 -0800 Subject: [PATCH 12/12] Switch DynamicMethod samples from regions to methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restructure DynamicMethod.Examples.cs to use self-contained static methods instead of #region/#endregion directives. Each method creates its own DynamicMethod and is independently runnable — addressing feedback that samples should be copy-paste compilable. Three methods replace the many small regions: - MetadataAndProperties: Name, DeclaringType, Module, Attributes, etc. - DefineParameterAndGetParameters: parameter metadata - GetILGeneratorAndInvoke: IL emission, delegates, and Invoke Update tags in DynamicMethod.cs and samples.json to use method= instead of region= for Examples.cs entries. Overview.cs and CtorOwnerType.cs retain their existing region-based approach (single self-contained regions). Addresses feedback from jkotas on PR #124407. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Emit/DynamicMethod.CtorOwnerType.cs | 76 +++---- .../Reflection/Emit/DynamicMethod.Examples.cs | 196 +++++++----------- .../Reflection/Emit/DynamicMethod.Overview.cs | 60 +++--- .../samples/samples.json | 40 ++-- .../System/Reflection/Emit/DynamicMethod.cs | 32 +-- 5 files changed, 180 insertions(+), 224 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs index e328eafe12bc33..4443aaa80f733a 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs @@ -7,48 +7,48 @@ using System.Reflection; using System.Reflection.Emit; -#region OwnerTypeAccess -// A DynamicMethod associated with a type can access its private members. -DynamicMethod changeID = new( - "", typeof(int), [typeof(Example), typeof(int)], typeof(Example)); - -// Get a FieldInfo for the private field 'id'. -FieldInfo fid = typeof(Example).GetField("id", BindingFlags.NonPublic | BindingFlags.Instance)!; - -ILGenerator ilg = changeID.GetILGenerator(); -// Push current value of 'id' onto the stack. -ilg.Emit(OpCodes.Ldarg_0); -ilg.Emit(OpCodes.Ldfld, fid); -// Store the new value. -ilg.Emit(OpCodes.Ldarg_0); -ilg.Emit(OpCodes.Ldarg_1); -ilg.Emit(OpCodes.Stfld, fid); -// Return the old value. -ilg.Emit(OpCodes.Ret); - -// Static-style delegate: takes (Example, int), returns old id. -var setId = changeID.CreateDelegate>(); - -Example ex = new(42); -int oldId = setId(ex, 1492); -Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}"); - -// Instance-style delegate: bind to a specific Example instance. -var setBound = (Func)changeID.CreateDelegate(typeof(Func), ex); -oldId = setBound(2700); -Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}"); -#endregion OwnerTypeAccess - -// Verify -if (ex.ID != 2700) -{ - Console.Error.WriteLine($"FAIL: expected 2700, got {ex.ID}"); - return 1; -} +OwnerTypeAccess(); Console.WriteLine("Passed."); return 0; +void OwnerTypeAccess() +{ + // A DynamicMethod associated with a type can access its private members. + DynamicMethod changeID = new( + "", typeof(int), [typeof(Example), typeof(int)], typeof(Example)); + + // Get a FieldInfo for the private field 'id'. + FieldInfo fid = typeof(Example).GetField("id", BindingFlags.NonPublic | BindingFlags.Instance)!; + + ILGenerator ilg = changeID.GetILGenerator(); + // Push current value of 'id' onto the stack. + ilg.Emit(OpCodes.Ldarg_0); + ilg.Emit(OpCodes.Ldfld, fid); + // Store the new value. + ilg.Emit(OpCodes.Ldarg_0); + ilg.Emit(OpCodes.Ldarg_1); + ilg.Emit(OpCodes.Stfld, fid); + // Return the old value. + ilg.Emit(OpCodes.Ret); + + // Static-style delegate: takes (Example, int), returns old id. + var setId = changeID.CreateDelegate>(); + + Example ex = new(42); + int oldId = setId(ex, 1492); + Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}"); + + // Instance-style delegate: bind to a specific Example instance. + var setBound = (Func)changeID.CreateDelegate(typeof(Func), ex); + oldId = setBound(2700); + Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}"); + + // Verify + if (ex.ID != 2700) + throw new Exception($"FAIL: expected 2700, got {ex.ID}"); +} + // Helper types public class Example(int id) { diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs index 403ca053059c49..ed0eec92e4518e 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Examples.cs @@ -1,136 +1,92 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // Runnable examples for DynamicMethod XML doc comments. -// Each #region is referenced by tags in DynamicMethod.cs. +// Each local function is a self-contained sample referenced by tags in DynamicMethod.cs. // Run: dotnet run DynamicMethod.Examples.cs using System.Globalization; using System.Reflection; using System.Reflection.Emit; -// Create a DynamicMethod shared by the property/method examples below. -DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); -int failures = 0; +MetadataAndProperties(); +DefineParameterAndGetParameters(); +GetILGeneratorAndInvoke(); -void Fail(string name, string message) +Console.WriteLine("All examples passed."); +return 0; + +void MetadataAndProperties() { - Console.Error.WriteLine($"FAIL: {name} — {message}"); - failures++; + // Create a dynamic method associated with a module. + DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); + + // Name: the name specified at creation. + Console.WriteLine($"Name: {hello.Name}"); + + // DeclaringType is always null for dynamic methods. + Console.WriteLine($"DeclaringType: {hello.DeclaringType?.ToString() ?? "(null)"}"); + + // ReflectedType is always null for dynamic methods. + Console.WriteLine($"ReflectedType: {hello.ReflectedType?.ToString() ?? "(null)"}"); + + // Module: the module the dynamic method is associated with. + Console.WriteLine($"Module: {hello.Module}"); + + // Attributes are always Public | Static. + Console.WriteLine($"Attributes: {hello.Attributes}"); + + // CallingConvention is always Standard. + Console.WriteLine($"CallingConvention: {hello.CallingConvention}"); + + // ReturnType: the return type specified at creation. + Console.WriteLine($"ReturnType: {hello.ReturnType}"); + + // ReturnTypeCustomAttributes: no way to set custom attributes on the return type. + ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes; + object[] returnAttributes = caProvider.GetCustomAttributes(true); + Console.WriteLine($"Return type custom attributes: {returnAttributes.Length}"); + + // InitLocals defaults to true — local variables are zero-initialized. + Console.WriteLine($"InitLocals: {hello.InitLocals}"); + + // ToString returns the method signature (return type, name, parameter types). + Console.WriteLine($"ToString: {hello.ToString()}"); } -#region Name -// The name specified when the dynamic method was created. -Console.WriteLine($"Name: {hello.Name}"); -#endregion -if (hello.Name != "Hello") Fail("Name", $"Expected 'Hello', got '{hello.Name}'"); - -#region DeclaringType -// DeclaringType is always null for dynamic methods. -Console.WriteLine($"DeclaringType: {hello.DeclaringType?.ToString() ?? "(null)"}"); -#endregion -if (hello.DeclaringType is not null) Fail("DeclaringType", "Expected null"); - -#region ReflectedType -// ReflectedType is always null for dynamic methods. -Console.WriteLine($"ReflectedType: {hello.ReflectedType?.ToString() ?? "(null)"}"); -#endregion -if (hello.ReflectedType is not null) Fail("ReflectedType", "Expected null"); - -#region Module -// The module the dynamic method is associated with. -Console.WriteLine($"Module: {hello.Module}"); -#endregion -if (hello.Module != typeof(string).Module) Fail("Module", "Expected System.Private.CoreLib module"); - -#region Attributes -// Dynamic methods always have Public | Static attributes. -Console.WriteLine($"Attributes: {hello.Attributes}"); -#endregion -if (hello.Attributes != (MethodAttributes.Public | MethodAttributes.Static)) - Fail("Attributes", $"Expected Public | Static, got {hello.Attributes}"); - -#region CallingConvention -// Dynamic methods always use Standard calling convention. -Console.WriteLine($"CallingConvention: {hello.CallingConvention}"); -#endregion -if (hello.CallingConvention != CallingConventions.Standard) - Fail("CallingConvention", $"Expected Standard, got {hello.CallingConvention}"); - -#region InitLocals -// InitLocals defaults to true — local variables are zero-initialized. -Console.WriteLine($"InitLocals: {hello.InitLocals}"); -#endregion -if (!hello.InitLocals) Fail("InitLocals", "Expected true"); - -#region ReturnType -// The return type specified when the dynamic method was created. -Console.WriteLine($"ReturnType: {hello.ReturnType}"); -#endregion -if (hello.ReturnType != typeof(int)) Fail("ReturnType", $"Expected Int32, got {hello.ReturnType}"); - -#region ReturnTypeCustomAttributes -// At present there is no way to set custom attributes on the return type, -// so the list is always empty. -ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes; -object[] returnAttributes = caProvider.GetCustomAttributes(true); -Console.WriteLine($"Return type custom attributes: {returnAttributes.Length}"); -#endregion -if (returnAttributes.Length != 0) Fail("ReturnTypeCustomAttributes", "Expected 0 attributes"); - -#region DefineParameter -// Optionally add parameter metadata (useful for debugging). -hello.DefineParameter(1, ParameterAttributes.In, "message"); -hello.DefineParameter(2, ParameterAttributes.In, "valueToReturn"); -#endregion - -#region GetParameters -// Retrieve parameter info after calling DefineParameter. -ParameterInfo[] parameters = hello.GetParameters(); -foreach (ParameterInfo p in parameters) - Console.WriteLine($" Param: {p.Name}, {p.ParameterType}, {p.Attributes}"); -#endregion -if (parameters.Length != 2) Fail("GetParameters", $"Expected 2 parameters, got {parameters.Length}"); - -#region ToString -// ToString returns the signature: return type, name, and parameter types. -string sig = hello.ToString(); -Console.WriteLine($"ToString: {sig}"); -#endregion -if (!sig.Contains("Hello")) Fail("ToString", $"Expected signature to contain 'Hello'"); - -// Emit a method body so we can test CreateDelegate and Invoke. -MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!; - -#region GetILGenerator -// Get an ILGenerator to emit the method body. -ILGenerator il = hello.GetILGenerator(); -il.Emit(OpCodes.Ldarg_0); -il.EmitCall(OpCodes.Call, writeString, null); -il.Emit(OpCodes.Ldarg_1); -il.Emit(OpCodes.Ret); -#endregion - -#region CreateDelegate -// Create a strongly-typed delegate for the dynamic method. -Func hi = hello.CreateDelegate>(); -int retval = hi("Hello from delegate!", 42); -Console.WriteLine($"Delegate returned: {retval}"); -#endregion -if (retval != 42) Fail("CreateDelegate", $"Expected 42, got {retval}"); - -#region Invoke -// Invoke the dynamic method via reflection (slower than a delegate). -object? objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, - ["Hello from Invoke!", 99], CultureInfo.InvariantCulture); -Console.WriteLine($"Invoke returned: {objRet}"); -#endregion -if (objRet is not 99) Fail("Invoke", $"Expected 99, got {objRet}"); - -if (failures > 0) +void DefineParameterAndGetParameters() { - Console.Error.WriteLine($"\n{failures} example(s) failed."); - return 1; + DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); + + // DefineParameter adds metadata such as name and attributes. + // Parameter positions are 1-based; position 0 refers to the return value. + hello.DefineParameter(1, ParameterAttributes.In, "message"); + hello.DefineParameter(2, ParameterAttributes.In, "valueToReturn"); + + // GetParameters retrieves the parameter info. + ParameterInfo[] parameters = hello.GetParameters(); + foreach (ParameterInfo p in parameters) + Console.WriteLine($" Param: {p.Name}, {p.ParameterType}, {p.Attributes}"); } -Console.WriteLine("\nAll examples passed."); -return 0; +void GetILGeneratorAndInvoke() +{ + DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); + MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!; + + // GetILGenerator returns an ILGenerator for emitting the method body. + ILGenerator il = hello.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); // push first arg (string) + il.EmitCall(OpCodes.Call, writeString, null); // Console.WriteLine(string) + il.Emit(OpCodes.Ldarg_1); // push second arg (int) + il.Emit(OpCodes.Ret); // return it + + // CreateDelegate produces a strongly-typed delegate for the dynamic method. + Func hi = hello.CreateDelegate>(); + int retval = hi("Hello from delegate!", 42); + Console.WriteLine($"Delegate returned: {retval}"); + + // Invoke calls the dynamic method via reflection (slower than a delegate). + object? objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, + ["Hello from Invoke!", 99], CultureInfo.InvariantCulture); + Console.WriteLine($"Invoke returned: {objRet}"); +} diff --git a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs index 278cb25601d1a6..453b9eff5bf9c1 100644 --- a/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs +++ b/src/libraries/System.Private.CoreLib/samples/System/Reflection/Emit/DynamicMethod.Overview.cs @@ -7,36 +7,36 @@ using System.Reflection; using System.Reflection.Emit; -#region CreateAndInvoke -// Create a dynamic method with return type int and two parameters (string, int). -DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); - -// Emit a body: print the string argument, then return the int argument. -MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!; -ILGenerator il = hello.GetILGenerator(); -il.Emit(OpCodes.Ldarg_0); -il.EmitCall(OpCodes.Call, writeString, null); -il.Emit(OpCodes.Ldarg_1); -il.Emit(OpCodes.Ret); - -// Create a delegate that represents the dynamic method. -Func hi = hello.CreateDelegate>(); - -// Execute via delegate. -int retval = hi("Hello, World!", 42); -Console.WriteLine($"Delegate returned: {retval}"); - -// Execute via Invoke (slower — requires boxing and array allocation). -object? objRet = hello.Invoke(null, ["Hello via Invoke!", 99]); -Console.WriteLine($"Invoke returned: {objRet}"); -#endregion CreateAndInvoke - -// Verify results -if (retval != 42 || objRet is not 99) -{ - Console.Error.WriteLine("FAIL: unexpected return values"); - return 1; -} +CreateAndInvoke(); Console.WriteLine("Passed."); return 0; + +void CreateAndInvoke() +{ + // Create a dynamic method with return type int and two parameters (string, int). + DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module); + + // Emit a body: print the string argument, then return the int argument. + MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!; + ILGenerator il = hello.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.EmitCall(OpCodes.Call, writeString, null); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ret); + + // Create a delegate that represents the dynamic method. + Func hi = hello.CreateDelegate>(); + + // Execute via delegate. + int retval = hi("Hello, World!", 42); + Console.WriteLine($"Delegate returned: {retval}"); + + // Execute via Invoke (slower — requires boxing and array allocation). + object? objRet = hello.Invoke(null, ["Hello via Invoke!", 99]); + Console.WriteLine($"Invoke returned: {objRet}"); + + // Verify results + if (retval != 42 || objRet is not 99) + throw new Exception("FAIL: unexpected return values"); +} diff --git a/src/libraries/System.Private.CoreLib/samples/samples.json b/src/libraries/System.Private.CoreLib/samples/samples.json index 32e75747b5fa52..3de27c911d92cd 100644 --- a/src/libraries/System.Private.CoreLib/samples/samples.json +++ b/src/libraries/System.Private.CoreLib/samples/samples.json @@ -1,22 +1,22 @@ { - "T:System.Reflection.Emit.DynamicMethod": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "region": "CreateAndInvoke", "title": "Creating and invoking a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Reflection.Module)": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "region": "CreateAndInvoke", "title": "Creating a DynamicMethod associated with a module" }, - "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Type)": { "file": "System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs", "region": "OwnerTypeAccess", "title": "Creating a DynamicMethod with an owner type" }, - "P:System.Reflection.Emit.DynamicMethod.Name": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "Name", "title": "Getting the name of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.DeclaringType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "DeclaringType", "title": "Getting the declaring type of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.ReflectedType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ReflectedType", "title": "Getting the reflected type of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.Module": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "Module", "title": "Getting the module of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.Attributes": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "Attributes", "title": "Getting the attributes of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.CallingConvention": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "CallingConvention", "title": "Getting the calling convention of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.ReturnType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ReturnType", "title": "Getting the return type of a DynamicMethod" }, - "P:System.Reflection.Emit.DynamicMethod.ReturnTypeCustomAttributes": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ReturnTypeCustomAttributes", "title": "Getting return type custom attributes" }, - "P:System.Reflection.Emit.DynamicMethod.InitLocals": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "InitLocals", "title": "Checking InitLocals on a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "ToString", "title": "Getting the string representation of a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "GetParameters", "title": "Getting parameter info from a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "DefineParameter", "title": "Defining parameters on a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "GetILGenerator", "title": "Getting the IL generator for a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.GetILGenerator(System.Int32)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "GetILGenerator", "title": "Getting the IL generator for a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "CreateDelegate", "title": "Creating a delegate from a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type,System.Object)": { "file": "System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs", "region": "OwnerTypeAccess", "title": "Creating a bound delegate from a DynamicMethod" }, - "M:System.Reflection.Emit.DynamicMethod.Invoke(System.Object,System.Reflection.BindingFlags,System.Reflection.Binder,System.Object[],System.Globalization.CultureInfo)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "region": "Invoke", "title": "Invoking a DynamicMethod via reflection" } + "T:System.Reflection.Emit.DynamicMethod": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "method": "CreateAndInvoke", "title": "Creating and invoking a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Reflection.Module)": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "method": "CreateAndInvoke", "title": "Creating a DynamicMethod associated with a module" }, + "M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Type)": { "file": "System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs", "method": "OwnerTypeAccess", "title": "Creating a DynamicMethod with an owner type" }, + "P:System.Reflection.Emit.DynamicMethod.Name": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "P:System.Reflection.Emit.DynamicMethod.DeclaringType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "P:System.Reflection.Emit.DynamicMethod.ReflectedType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "P:System.Reflection.Emit.DynamicMethod.Module": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "P:System.Reflection.Emit.DynamicMethod.Attributes": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "P:System.Reflection.Emit.DynamicMethod.CallingConvention": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "P:System.Reflection.Emit.DynamicMethod.ReturnType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "P:System.Reflection.Emit.DynamicMethod.ReturnTypeCustomAttributes": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "P:System.Reflection.Emit.DynamicMethod.InitLocals": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" }, + "M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "DefineParameterAndGetParameters", "title": "Defining and retrieving DynamicMethod parameters" }, + "M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "DefineParameterAndGetParameters", "title": "Defining and retrieving DynamicMethod parameters" }, + "M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "GetILGeneratorAndInvoke", "title": "Emitting IL and invoking a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.GetILGenerator(System.Int32)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "GetILGeneratorAndInvoke", "title": "Emitting IL and invoking a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "GetILGeneratorAndInvoke", "title": "Emitting IL and invoking a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type,System.Object)": { "file": "System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs", "method": "OwnerTypeAccess", "title": "Creating a bound delegate from a DynamicMethod" }, + "M:System.Reflection.Emit.DynamicMethod.Invoke(System.Object,System.Reflection.BindingFlags,System.Reflection.Binder,System.Object[],System.Globalization.CultureInfo)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "GetILGeneratorAndInvoke", "title": "Emitting IL and invoking a DynamicMethod" } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index c6b1e523cd193c..fa920b0ded79d2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -18,7 +18,7 @@ namespace System.Reflection.Emit /// /// /// The following example creates a dynamic method, emits a method body, and executes it via a delegate and via . - /// + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -141,7 +141,7 @@ public DynamicMethod(string name, /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. /// /// - /// + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -277,7 +277,7 @@ public DynamicMethod(string name, /// The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromExample, and the delegate calls are repeated. /// /// - /// + /// /// /// How to: Define and Execute Dynamic Methods /// Security Issues in Reflection Emit @@ -510,7 +510,7 @@ private void Init(string name, /// The following code example displays the method of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override string ToString() { @@ -538,7 +538,7 @@ public override string ToString() /// The following code example displays the name of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override string Name => _name; @@ -551,7 +551,7 @@ public override string ToString() /// The following code example displays the declaring type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override Type? DeclaringType => null; @@ -564,7 +564,7 @@ public override string ToString() /// The following code example displays the reflected type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override Type? ReflectedType => null; @@ -577,7 +577,7 @@ public override string ToString() /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override Module Module => _module; @@ -598,7 +598,7 @@ public override string ToString() /// The following code example displays the method attributes of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override MethodAttributes Attributes => _attributes; @@ -611,7 +611,7 @@ public override string ToString() /// The following code example displays the calling convention of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override CallingConventions CallingConvention => _callingConvention; @@ -633,7 +633,7 @@ public override string ToString() /// The following code example displays the parameters of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override ParameterInfo[] GetParameters() => GetParametersAsSpan().ToArray(); @@ -832,7 +832,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example displays the return type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override Type ReturnType => _returnType; @@ -854,7 +854,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example shows how to display the custom attributes of the return type of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public override ICustomAttributeProvider ReturnTypeCustomAttributes => new EmptyCAHolder(); @@ -876,7 +876,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example shows how to define parameter information for a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public ParameterBuilder? DefineParameter(int position, ParameterAttributes attributes, string? parameterName) { @@ -905,7 +905,7 @@ public override bool IsDefined(Type attributeType, bool inherit) /// The following code example creates a dynamic method that takes two parameters. The example emits a simple function body that prints the first parameter to the console, and the example uses the second parameter as the return value of the method. The example completes the method by creating a delegate, invokes the delegate with different parameters, and finally invokes the dynamic method using the method. /// /// - /// + /// /// /// How to: Define and Execute Dynamic Methods public ILGenerator GetILGenerator() @@ -922,7 +922,7 @@ public ILGenerator GetILGenerator() /// The following code example displays the property of a dynamic method. This code example is part of a larger example provided for the class. /// /// - /// + /// /// public bool InitLocals {