DynamicMethod 构造函数

定义

创建动态方法。

重载

DynamicMethod(String, Type, Type[])

初始化匿名托管的动态方法,指定方法名称、返回类型和参数类型。

DynamicMethod(String, Type, Type[], Boolean)

初始化匿名托管的动态方法,同时指定方法名称、返回类型、参数类型并指定是否应针对动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员跳过实时 (JIT) 可见性检查。

DynamicMethod(String, Type, Type[], Module)

创建一个对模块全局有效的动态方法,指定方法名称、返回类型、参数类型和模块。

DynamicMethod(String, Type, Type[], Type)

创建动态方法,并指定方法的名称、返回类型、参数类型和此动态方法与之在逻辑上相关联的类型。

DynamicMethod(String, Type, Type[], Module, Boolean)

创建一个对模块全局有效的动态方法,指定方法名称、返回类型、参数类型和模块,并指定动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员是否应跳过实时 (JIT) 可见性检查。

DynamicMethod(String, Type, Type[], Type, Boolean)

创建一个动态方法,指定方法名称、返回类型、参数类型,以及与该动态方法逻辑上相关联的类型,并指定动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员是否应跳过实时 (JIT) 可见性检查。

DynamicMethod(String, MethodAttributes, CallingConventions, Type, Type[], Module, Boolean)

创建一个对模块全局有效的动态方法,指定方法名称、属性、调用约定、返回类型、参数类型和模块,并指定动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员是否应跳过实时 (JIT) 可见性检查。

DynamicMethod(String, MethodAttributes, CallingConventions, Type, Type[], Type, Boolean)

创建一个动态方法,指定方法名称、属性、调用约定、返回类型、参数类型,以及与该动态方法逻辑上相关联的类型,并指定动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员是否应跳过实时 (JIT) 可见性检查。

DynamicMethod(String, Type, Type[])

Source:
DynamicMethod.cs
Source:
DynamicMethod.cs
Source:
DynamicMethod.cs

初始化匿名托管的动态方法,指定方法名称、返回类型和参数类型。

public:
 DynamicMethod(System::String ^ name, Type ^ returnType, cli::array <Type ^> ^ parameterTypes);
public DynamicMethod (string name, Type? returnType, Type[]? parameterTypes);
public DynamicMethod (string name, Type returnType, Type[] parameterTypes);
new System.Reflection.Emit.DynamicMethod : string * Type * Type[] -> System.Reflection.Emit.DynamicMethod
Public Sub New (name As String, returnType As Type, parameterTypes As Type())

参数

name
String

动态方法的名称。 它可以是长度为零的字符串,但不能为 null

returnType
Type

一个 Type 对象,用于指定动态方法的返回类型,如果此方法没有返回类型,则为 null

parameterTypes
Type[]

指定动态方法的参数类型的 Type 对象数组,如果此方法不具有任何参数,则为 null

例外

parameterTypes 的元素为 nullVoid

namenull

.NET Framework 和 2.1 之前的 .NET Core 版本:returnType是返回 true的类型IsByRef

注解

此构造函数创建的动态方法与匿名程序集(而不是现有类型或模块)相关联。 匿名程序集的存在只是为了为动态方法提供沙盒环境,即将它们与其他代码隔离开来。 此环境使动态方法可以安全地由部分受信任的代码发出和执行。

此构造函数指定对动态方法的 Microsoft 中间语言 (MSIL) 强制执行实时 (JIT) 可见性检查。 也就是说,动态方法中的代码可以访问公共类的公共方法。 如果方法尝试访问在 Visual Basic) 中为 、 protected或 (Friend 的类型或internal成员private,则会引发异常。 若要创建一个能够跳过 JIT 可见性检查的动态方法,请使用 DynamicMethod(String, Type, Type[], Boolean) 构造函数。

构造匿名托管的动态方法时,将包含发出程序集的调用堆栈。 调用 方法时,将使用发出程序集的权限,而不是实际调用方的权限。 因此,动态方法的执行特权级别不能高于发出它的程序集的特权级别,即使它传递给具有较高信任级别的程序集并由其执行也是如此。

此构造函数指定方法属性 MethodAttributes.PublicMethodAttributes.Static,以及调用约定 CallingConventions.Standard

注意

此构造函数是在 .NET Framework 3.5 或更高版本中引入的。

另请参阅

适用于

DynamicMethod(String, Type, Type[], Boolean)

Source:
DynamicMethod.cs
Source:
DynamicMethod.cs
Source:
DynamicMethod.cs

初始化匿名托管的动态方法,同时指定方法名称、返回类型、参数类型并指定是否应针对动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员跳过实时 (JIT) 可见性检查。

public:
 DynamicMethod(System::String ^ name, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, bool restrictedSkipVisibility);
public DynamicMethod (string name, Type? returnType, Type[]? parameterTypes, bool restrictedSkipVisibility);
public DynamicMethod (string name, Type returnType, Type[] parameterTypes, bool restrictedSkipVisibility);
new System.Reflection.Emit.DynamicMethod : string * Type * Type[] * bool -> System.Reflection.Emit.DynamicMethod
Public Sub New (name As String, returnType As Type, parameterTypes As Type(), restrictedSkipVisibility As Boolean)

参数

name
String

动态方法的名称。 它可以是长度为零的字符串,但不能为 null

returnType
Type

一个 Type 对象,用于指定动态方法的返回类型,如果此方法没有返回类型,则为 null

parameterTypes
Type[]

指定动态方法的参数类型的 Type 对象数组,如果此方法不具有任何参数,则为 null

restrictedSkipVisibility
Boolean

如果为 true,则跳过针对动态方法的 MSIL 访问的类型和成员进行的 JIT 可见性检查,含此限制:包含这些类型和成员的程序集的信任级别必须等于或小于发出动态方法的调用堆栈的信任级别;否则为 false

例外

parameterTypes 的元素为 nullVoid

namenull

.NET Framework 和 2.1 之前的 .NET Core 版本:returnType是返回 true的类型IsByRef

注解

此构造函数创建的动态方法与匿名程序集(而不是现有类型或模块)相关联。 匿名程序集的存在只是为了为动态方法提供沙盒环境,即将它们与其他代码隔离开来。 此环境使动态方法可以安全地由部分受信任的代码发出和执行。

匿名托管的动态方法不能自动访问 Visual Basic) 中为 private、 或 (Friend 的任何类型或internalprotected成员。 这不同于与现有类型或模块关联的动态方法,这些方法有权访问其关联范围内的隐藏成员。

如果动态方法必须访问的类型或成员为 private、 或 internalprotected请指定 truerestrictedSkipVisibility 这为动态方法提供了对这些成员的受限访问权限。 也就是说,仅当满足以下条件时,才能访问成员:

  • 目标成员属于一个程序集,该程序集的信任级别等于或低于发出动态方法的调用堆栈。

  • 向发出动态方法的调用堆栈授予 ReflectionPermission 标志 ReflectionPermissionFlag.RestrictedMemberAccess 。 当以完全信任方式执行代码时,始终如此。 对于部分受信任的代码,仅当主机显式授予权限时才为 true。

    重要

    如果未授予权限,则在调用 或调用动态方法时 CreateDelegate (而不是调用此构造函数时)时引发安全异常。 无需特殊权限即可发出动态方法。

例如,如果已向调用堆栈授予受限成员访问权限,则创建的 restrictedSkipVisibility 动态方法设置为 true 可以访问调用堆栈上任何程序集的私有成员。 如果动态方法是在调用堆栈上使用部分受信任的代码创建的,则它无法访问.NET Framework程序集中某个类型的私有成员,因为此类程序集是完全受信任的。

如果 restrictedSkipVisibilityfalse,则强制执行 JIT 可见性检查。 动态方法中的代码有权访问公共类的公共方法,如果它尝试访问的类型或成员为 privateprotectedinternal,则会引发异常。

构造匿名托管的动态方法时,将包含发出程序集的调用堆栈。 调用 方法时,将使用发出调用堆栈的权限,而不是实际调用方的权限。 因此,动态方法的执行特权级别不能高于发出它的程序集的特权级别,即使它传递给具有较高信任级别的程序集并由其执行也是如此。

此构造函数指定方法属性 MethodAttributes.PublicMethodAttributes.Static,以及调用约定 CallingConventions.Standard

注意

此构造函数是在 .NET Framework 3.5 或更高版本中引入的。

另请参阅

适用于

DynamicMethod(String, Type, Type[], Module)

Source:
DynamicMethod.cs
Source:
DynamicMethod.cs
Source:
DynamicMethod.cs

创建一个对模块全局有效的动态方法,指定方法名称、返回类型、参数类型和模块。

public:
 DynamicMethod(System::String ^ name, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, System::Reflection::Module ^ m);
public DynamicMethod (string name, Type? returnType, Type[]? parameterTypes, System.Reflection.Module m);
public DynamicMethod (string name, Type returnType, Type[] parameterTypes, System.Reflection.Module m);
new System.Reflection.Emit.DynamicMethod : string * Type * Type[] * System.Reflection.Module -> System.Reflection.Emit.DynamicMethod
Public Sub New (name As String, returnType As Type, parameterTypes As Type(), m As Module)

参数

name
String

动态方法的名称。 它可以是长度为零的字符串,但不能为 null

returnType
Type

一个 Type 对象,用于指定动态方法的返回类型,如果此方法没有返回类型,则为 null

parameterTypes
Type[]

指定动态方法的参数类型的 Type 对象数组,如果此方法不具有任何参数,则为 null

m
Module

一个 Module,表示动态方法将与之逻辑关联的模块。

例外

parameterTypes 的元素为 nullVoid

- 或 -

m 是为动态方法提供匿名承载的模块。

namenull

mnull

.NET Framework 和 2.1 之前的 .NET Core 版本:returnType是返回 true的类型IsByRef

示例

下面的代码示例创建一个采用两个参数的动态方法。 该示例发出一个简单的函数体,该函数体将第一个参数打印到控制台,该示例使用第二个参数作为 方法的返回值。 该示例通过创建委托完成方法,使用不同参数调用委托,最后使用 Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) 方法调用动态方法。

using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;

public ref class Test
{   
};

// Declare a delegate that will be used to execute the completed
// dynamic method.
delegate int HelloInvoker(String^ msg, int ret);

int main()
{
    // Create an array that specifies the types of the parameters
    // of the dynamic method. This method has a string parameter
    // and an int parameter.
    array<Type^>^ helloArgs = {String::typeid, int::typeid};

    // Create a dynamic method with the name "Hello", a return type
    // of int, and two parameters whose types are specified by the
    // array helloArgs. Create the method in the module that
    // defines the Test class.
    DynamicMethod^ hello = gcnew DynamicMethod("Hello", 
        int::typeid,
        helloArgs,
        Test::typeid->Module);

    // Create an array that specifies the parameter types of the
    // overload of Console.WriteLine to be used in Hello.
    array<Type^>^ writeStringArgs = {String::typeid};
    // Get the overload of Console.WriteLine that has one
    // String parameter.
    MethodInfo^ writeString =
        Console::typeid->GetMethod("WriteLine", writeStringArgs);

    // Get an ILGenerator and emit a body for the dynamic method.
    ILGenerator^ ilgen = hello->GetILGenerator();
    // Load the first argument, which is a string, onto the stack.
    ilgen->Emit(OpCodes::Ldarg_0);
    // Call the overload of Console.WriteLine that prints a string.
    ilgen->EmitCall(OpCodes::Call, writeString, nullptr);
    // The Hello method returns the value of the second argument;
    // to do this, load the onto the stack and return.
    ilgen->Emit(OpCodes::Ldarg_1);
    ilgen->Emit(OpCodes::Ret);

    // Create a delegate that represents the dynamic method. This
    // action completes the method, and any further attempts to
    // change the method will cause an exception.
    HelloInvoker^ helloDelegate =
        (HelloInvoker^) hello->CreateDelegate(HelloInvoker::typeid);

    // Use the delegate to execute the dynamic method. Save and
    // print the return value.
    int returnValue = helloDelegate("\r\nHello, World!", 42);
    Console::WriteLine("helloDelegate(\"Hello, World!\", 42) returned {0}",
        returnValue);

    // Do it again, with different arguments.
    returnValue = helloDelegate("\r\nHi, Mom!", 5280);
    Console::WriteLine("helloDelegate(\"Hi, Mom!\", 5280) returned {0}",
        returnValue);

    // Create an array of arguments to use with the Invoke method.
    array<Object^>^ delegateArgs = {"\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 ValueType arguments
    // must be boxed.
    Object^ returnValueObject = hello->Invoke(nullptr, delegateArgs);
    Console::WriteLine("hello.Invoke returned {0}", returnValueObject);
}
using System;
using System.Reflection;
using System.Reflection.Emit;
using Microsoft.VisualBasic;

public class Test
{
    // Declare a delegate that will be used to execute the completed
    // dynamic method.
    private delegate int HelloInvoker(string msg, int ret);

    public static void Main()
    {
        // Create an array that specifies the types of the parameters
        // of the dynamic method. This method has a string parameter
        // and an int parameter.
        Type[] helloArgs = {typeof(string), typeof(int)};

        // Create a dynamic method with the name "Hello", a return type
        // of int, and two parameters whose types are specified by the
        // array helloArgs. Create the method in the module that
        // defines the Test class.
        DynamicMethod hello = new DynamicMethod("Hello",
            typeof(int),
            helloArgs,
            typeof(Test).Module);

        // 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.
        ILGenerator il = hello.GetILGenerator();
        // 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);

        // Create a delegate that represents the dynamic method. This
        // action completes the method, and any further attempts to
        // change the method will cause an exception.
        HelloInvoker hi =
            (HelloInvoker) hello.CreateDelegate(typeof(HelloInvoker));

        // Use the delegate to execute the dynamic method. Save and
        // print the return value.
        int retval = hi("\r\nHello, World!", 42);
        Console.WriteLine("Executing delegate hi(\"Hello, World!\", 42) returned {0}",
            retval);

        // Do it again, with different arguments.
        retval = hi("\r\nHi, Mom!", 5280);
        Console.WriteLine("Executing delegate hi(\"Hi, Mom!\", 5280) returned {0}",
            retval);

        // 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 ValueType arguments
        // must be boxed.
        object objRet = hello.Invoke(null, invokeArgs);
        Console.WriteLine("hello.Invoke returned {0}", objRet);
    }
}
Imports System.Reflection
Imports System.Reflection.Emit

Public Class Test
    ' Declare a delegate that will be used to execute the completed
    ' dynamic method. 
    Private Delegate Function HelloInvoker(ByVal msg As String, _
        ByVal ret As Integer) As Integer

    Public Shared Sub Main()
        ' Create an array that specifies the types of the parameters
        ' of the dynamic method. This method has a String parameter
        ' and an Integer parameter.
        Dim helloArgs() As Type = {GetType(String), GetType(Integer)}

        ' Create a dynamic method with the name "Hello", a return type
        ' of Integer, and two parameters whose types are specified by
        ' the array helloArgs. Create the method in the module that
        ' defines the Test class.
        Dim hello As New DynamicMethod("Hello", _
            GetType(Integer), _
            helloArgs, _
            GetType(Test).Module)

        ' Create an array that specifies the parameter types of the
        ' overload of Console.WriteLine to be used in Hello.
        Dim writeStringArgs() As Type = {GetType(String)}
        ' Get the overload of Console.WriteLine that has one
        ' String parameter.
        Dim writeString As MethodInfo = GetType(Console). _
            GetMethod("WriteLine", writeStringArgs) 

        ' Get an ILGenerator and emit a body for the dynamic method.
        Dim il As ILGenerator = hello.GetILGenerator()
        ' 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, Nothing)
        ' 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)

        ' Create a delegate that represents the dynamic method. This
        ' action completes the method, and any further attempts to
        ' change the method will cause an exception.
    Dim hi As HelloInvoker = _
            hello.CreateDelegate(GetType(HelloInvoker))

        ' Use the delegate to execute the dynamic method. Save and
        ' print the return value.
        Dim retval As Integer = hi(vbCrLf & "Hello, World!", 42)
        Console.WriteLine("Executing delegate hi(""Hello, World!"", 42) returned " _
            & retval)

        ' Do it again, with different arguments.
        retval = hi(vbCrLf & "Hi, Mom!", 5280)
        Console.WriteLine("Executing delegate hi(""Hi, Mom!"", 5280) returned " _
            & retval)

        ' Create an array of arguments to use with the Invoke method.
        Dim invokeArgs() As Object = {vbCrLf & "Hello, 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 ValueType arguments
        ' must be boxed. Note that this overload of Invoke is 
        ' inherited from MethodBase, and simply calls the more 
        ' complete overload of Invoke.
        Dim objRet As Object = hello.Invoke(Nothing, invokeArgs)
        Console.WriteLine("hello.Invoke returned " & objRet)
    End Sub
End Class

' This code example produces the following output:
'
'Hello, World!
'Executing delegate hi("Hello, World!", 42) returned 42
'
'Hi, Mom!
'Executing delegate hi("Hi, Mom!", 5280) returned 5280
'
'Hello, World!
'hello.Invoke returned 42
'

注解

此构造函数指定方法属性 MethodAttributes.PublicMethodAttributes.Static,调用约定 CallingConventions.Standard,并且不会跳过实时 (JIT) 可见性检查。

使用此构造函数创建的动态方法可以访问 Visual Basic 中的公共和 internal (Friend ,) 模块 m中包含的所有类型的成员。

注意

为了向后兼容,如果以下条件都为 true,则此构造函数要求SecurityPermission使用 标志:m是调用模块以外的模块,并且 具有 ReflectionPermissionFlag.MemberAccess 标志的 对 ReflectionPermissionSecurityPermissionFlag.ControlEvidence 的需求已失败。 如果 对 的需求 SecurityPermission 成功,则允许该操作。

另请参阅

适用于

DynamicMethod(String, Type, Type[], Type)

Source:
DynamicMethod.cs
Source:
DynamicMethod.cs
Source:
DynamicMethod.cs

创建动态方法,并指定方法的名称、返回类型、参数类型和此动态方法与之在逻辑上相关联的类型。

public:
 DynamicMethod(System::String ^ name, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, Type ^ owner);
public DynamicMethod (string name, Type? returnType, Type[]? parameterTypes, Type owner);
public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Type owner);
new System.Reflection.Emit.DynamicMethod : string * Type * Type[] * Type -> System.Reflection.Emit.DynamicMethod
Public Sub New (name As String, returnType As Type, parameterTypes As Type(), owner As Type)

参数

name
String

动态方法的名称。 它可以是长度为零的字符串,但不能为 null

returnType
Type

一个 Type 对象,用于指定动态方法的返回类型,如果此方法没有返回类型,则为 null

parameterTypes
Type[]

指定动态方法的参数类型的 Type 对象数组,如果此方法不具有任何参数,则为 null

owner
Type

动态方法与之在逻辑上相关联的 Type。 动态方法有权访问此类型的所有成员。

例外

parameterTypes 的元素为 nullVoid

- 或 -

owner 是一个接口、数组、开放式泛型类型,或者是泛型类型或方法的类型参数。

namenull

ownernull

.NET Framework和 .NET Core 版本早于 2.1: returnType 是返回 true的类型IsByRef

示例

下面的代码示例创建在 DynamicMethod 逻辑上与类型关联的 。 此关联使它能够访问该类型的私有成员。

该代码示例定义了一个具有私有字段的名为 的 Example 类、一个派生自第一个类的名为 DerivedFromExample 的类、一个名为 的 UseLikeStatic 委托类型,该类返回 Int32 并具有 类型 Example 为 和 Int32的参数,以及一个名为 的 UseLikeInstance 委托类型,该 Int32 类型返回 并具有一个 类型 Int32参数。

然后,示例代码创建一个 , DynamicMethod 用于更改 实例 Example 的私有字段并返回以前的值。

注意

通常,更改类的内部字段不是面向对象的编码做法。

示例代码创建 的 Example 实例,然后创建两个委托。 第一个 类型为 UseLikeStatic,其参数与动态方法相同。 第二个 类型为 UseLikeInstance,缺少类型为) 的第 Example 一个参数 (。 此委托是使用 CreateDelegate(Type, Object) 方法重载创建的;该方法重载的第二个参数是 的 Example实例,在本例中是刚刚创建的实例,该实例绑定到新创建的委托。 每当调用该委托时,动态方法就会作用于 的 Example绑定实例。

注意

这是.NET Framework 2.0 中引入的委托绑定的宽松规则以及 方法的新重载Delegate.CreateDelegate的示例。 有关更多信息,请参见 Delegate 类。

调用UseLikeStatic委托,传入绑定到委托的 UseLikeInstance 实例Example。 然后调用委托 UseLikeInstance ,以便两个委托对 的同一实例 Example执行操作。 内部字段的值更改在每次调用后显示。 最后,委托 UseLikeInstance 绑定到 的 DerivedFromExample实例,并重复委托调用。

using System;
using System.Reflection;
using System.Reflection.Emit;

// These classes are for demonstration purposes.
//
public class Example
{
    private int id = 0;
    public Example(int id)
    {
        this.id = id;
    }
    public int ID { get { return id; }}
}

public class DerivedFromExample : Example
{
    public DerivedFromExample(int id) : base(id) {}
}

// Two delegates are declared: UseLikeInstance treats the dynamic
// method as if it were an instance method, and UseLikeStatic
// treats the dynamic method in the ordinary fashion.
//
public delegate int UseLikeInstance(int newID);
public delegate int UseLikeStatic(Example ex, int newID);

public class Demo
{
    public static void Main()
    {
        // This dynamic method changes the private id field. It has
        // no name; it returns the old id value (return type int);
        // it takes two parameters, an instance of Example and
        // an int that is the new value of id; and it is declared
        // with Example as the owner type, so it can access all
        // members, public and private.
        //
        DynamicMethod changeID = new DynamicMethod(
            "",
            typeof(int),
            new Type[] { 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 the current value of the id field onto the
        // evaluation stack. It's an instance field, so load the
        // instance of Example before accessing the field.
        ilg.Emit(OpCodes.Ldarg_0);
        ilg.Emit(OpCodes.Ldfld, fid);

        // Load the instance of Example again, load the new value
        // of id, and store the new field value.
        ilg.Emit(OpCodes.Ldarg_0);
        ilg.Emit(OpCodes.Ldarg_1);
        ilg.Emit(OpCodes.Stfld, fid);

        // The original value of the id field is now the only
        // thing on the stack, so return from the call.
        ilg.Emit(OpCodes.Ret);

        // Create a delegate that uses changeID in the ordinary
        // way, as a static method that takes an instance of
        // Example and an int.
        //
        UseLikeStatic uls =
            (UseLikeStatic) changeID.CreateDelegate(
                typeof(UseLikeStatic)
            );

        // Create an instance of Example with an id of 42.
        //
        Example ex = new Example(42);

        // Create a delegate that is bound to the instance of
        // of Example. This is possible because the first
        // parameter of changeID is of type Example. The
        // delegate has all the parameters of changeID except
        // the first.
        UseLikeInstance uli =
            (UseLikeInstance) changeID.CreateDelegate(
                typeof(UseLikeInstance),
                ex
            );

        // First, change the value of id by calling changeID as
        // a static method, passing in the instance of Example.
        //
        Console.WriteLine(
            "Change the value of id; previous value: {0}",
            uls(ex, 1492)
        );

        // Change the value of id again using the delegate bound
        // to the instance of Example.
        //
        Console.WriteLine(
            "Change the value of id; previous value: {0}",
            uli(2700)
        );

        Console.WriteLine("Final value of id: {0}", ex.ID);

        // Now repeat the process with a class that derives
        // from Example.
        //
        DerivedFromExample dfex = new DerivedFromExample(71);

        uli = (UseLikeInstance) changeID.CreateDelegate(
                typeof(UseLikeInstance),
                dfex
            );

        Console.WriteLine(
            "Change the value of id; previous value: {0}",
            uls(dfex, 73)
        );
        Console.WriteLine(
            "Change the value of id; previous value: {0}",
            uli(79)
        );
        Console.WriteLine("Final value of id: {0}", dfex.ID);
    }
}

/* This code example produces the following output:

Change the value of id; previous value: 42
Change the value of id; previous value: 1492
Final value of id: 2700
Change the value of id; previous value: 71
Change the value of id; previous value: 73
Final value of id: 79
 */
Imports System.Reflection
Imports System.Reflection.Emit

' These classes are for demonstration purposes.
'
Public Class Example
    Private _id As Integer = 0
    
    Public Sub New(ByVal newId As Integer) 
        _id = newId    
    End Sub
    
    Public ReadOnly Property ID() As Integer 
        Get
            Return _id
        End Get
    End Property 
End Class

Public Class DerivedFromExample
    Inherits Example
    
    Public Sub New(ByVal newId As Integer) 
        MyBase.New(newId)
    End Sub
End Class
 
' Two delegates are declared: UseLikeInstance treats the dynamic
' method as if it were an instance method, and UseLikeStatic
' treats the dynamic method in the ordinary fashion.
' 
Public Delegate Function UseLikeInstance(ByVal newID As Integer) _
    As Integer 
Public Delegate Function UseLikeStatic(ByVal ex As Example, _
    ByVal newID As Integer) As Integer 

Public Class Demo
    
    Public Shared Sub Main() 
        ' This dynamic method changes the private _id field. It 
        ' has no name; it returns the old _id value (return type 
        ' Integer); it takes two parameters, an instance of Example 
        ' and an Integer that is the new value of _id; and it is 
        ' declared with Example as the owner type, so it can 
        ' access all members, public and private.
        '
        Dim changeID As New DynamicMethod( _
            "", _
            GetType(Integer), _
            New Type() {GetType(Example), GetType(Integer)}, _
            GetType(Example) _
        )
        
        ' Get a FieldInfo for the private field '_id'.
        Dim fid As FieldInfo = GetType(Example).GetField( _
            "_id", _
            BindingFlags.NonPublic Or BindingFlags.Instance _
        )
        
        Dim ilg As ILGenerator = changeID.GetILGenerator()
        
        ' Push the current value of the id field onto the 
        ' evaluation stack. It's an instance field, so load the
        ' instance of Example before accessing the field.
        ilg.Emit(OpCodes.Ldarg_0)
        ilg.Emit(OpCodes.Ldfld, fid)
        
        ' Load the instance of Example again, load the new value 
        ' of id, and store the new field value. 
        ilg.Emit(OpCodes.Ldarg_0)
        ilg.Emit(OpCodes.Ldarg_1)
        ilg.Emit(OpCodes.Stfld, fid)
        
        ' The original value of the id field is now the only 
        ' thing on the stack, so return from the call.
        ilg.Emit(OpCodes.Ret)
        
        
        ' Create a delegate that uses changeID in the ordinary
        ' way, as a static method that takes an instance of
        ' Example and an Integer.
        '
        Dim uls As UseLikeStatic = CType( _
            changeID.CreateDelegate(GetType(UseLikeStatic)), _
            UseLikeStatic _
        )
        
        ' Create an instance of Example with an id of 42.
        '
        Dim ex As New Example(42)
        
        ' Create a delegate that is bound to the instance of 
        ' of Example. This is possible because the first 
        ' parameter of changeID is of type Example. The 
        ' delegate has all the parameters of changeID except
        ' the first.
        Dim uli As UseLikeInstance = CType( _
            changeID.CreateDelegate( _
                GetType(UseLikeInstance), _
                ex), _
            UseLikeInstance _
        )
        
        ' First, change the value of _id by calling changeID as
        ' a static method, passing in the instance of Example.
        '
        Console.WriteLine( _
            "Change the value of _id; previous value: {0}", _
            uls(ex, 1492) _
        )
        
        ' Change the value of _id again using the delegate 
        ' bound to the instance of Example.
        '
        Console.WriteLine( _
            "Change the value of _id; previous value: {0}", _
            uli(2700) _
        )
        
        Console.WriteLine("Final value of _id: {0}", ex.ID)
    

        ' Now repeat the process with a class that derives
        ' from Example.
        '
        Dim dfex As New DerivedFromExample(71)

        uli = CType( _
            changeID.CreateDelegate( _
                GetType(UseLikeInstance), _
                dfex), _
            UseLikeInstance _
        )

        Console.WriteLine( _
            "Change the value of _id; previous value: {0}", _
            uls(dfex, 73) _
        )
        Console.WriteLine( _
            "Change the value of _id; previous value: {0}", _
            uli(79) _
        )
        Console.WriteLine("Final value of _id: {0}", dfex.ID)

    End Sub
End Class

' This code example produces the following output:
'
'Change the value of _id; previous value: 42
'Change the value of _id; previous value: 1492
'Final value of _id: 2700
'Change the value of _id; previous value: 71
'Change the value of _id; previous value: 73
'Final value of _id: 79'

注解

使用此构造函数创建的动态方法有权访问类型 owner的所有成员,以及 Visual Basic 中的公共和 internal (Friend ,) 包含 owner的模块中所有其他类型的成员。

此构造函数指定方法特性 MethodAttributes.PublicMethodAttributes.Static,调用约定 CallingConventions.Standard,并且不会跳过实时 (JIT) 可见性检查。

注意

为了向后兼容,如果以下条件都为 true,则此构造函数要求SecurityPermission使用 标志:owner位于调用模块以外的模块中,并且 具有 ReflectionPermissionFlag.MemberAccess 标志的 对 ReflectionPermissionSecurityPermissionFlag.ControlEvidence 的要求已失败。 如果 对 的需求 SecurityPermission 成功,则允许该操作。

另请参阅

适用于

DynamicMethod(String, Type, Type[], Module, Boolean)

Source:
DynamicMethod.cs
Source:
DynamicMethod.cs
Source:
DynamicMethod.cs

创建一个对模块全局有效的动态方法,指定方法名称、返回类型、参数类型和模块,并指定动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员是否应跳过实时 (JIT) 可见性检查。

public:
 DynamicMethod(System::String ^ name, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, System::Reflection::Module ^ m, bool skipVisibility);
public DynamicMethod (string name, Type? returnType, Type[]? parameterTypes, System.Reflection.Module m, bool skipVisibility);
public DynamicMethod (string name, Type returnType, Type[] parameterTypes, System.Reflection.Module m, bool skipVisibility);
new System.Reflection.Emit.DynamicMethod : string * Type * Type[] * System.Reflection.Module * bool -> System.Reflection.Emit.DynamicMethod
Public Sub New (name As String, returnType As Type, parameterTypes As Type(), m As Module, skipVisibility As Boolean)

参数

name
String

动态方法的名称。 它可以是长度为零的字符串,但不能为 null

returnType
Type

一个 Type 对象,用于指定动态方法的返回类型,如果此方法没有返回类型,则为 null

parameterTypes
Type[]

指定动态方法的参数类型的 Type 对象数组,如果此方法不具有任何参数,则为 null

m
Module

一个 Module,表示动态方法将与之逻辑关联的模块。

skipVisibility
Boolean

若要跳过对动态方法的 MSIL 访问的类型和成员的 JIT 可见性检查,则为 true

例外

parameterTypes 的元素为 nullVoid

- 或 -

m 是为动态方法提供匿名承载的模块。

namenull

mnull

.NET Framework和 .NET Core 版本早于 2.1: returnType 是返回 true的类型IsByRef

注解

此构造函数指定方法特性 MethodAttributes.PublicMethodAttributes.Static,并调用约定 CallingConventions.Standard

使用此构造函数创建的动态方法可以访问 Visual Basic 中的公共和 internal (Friend ,) 包含模块 m中的所有类型的成员。 跳过 JIT 编译器的可见性检查,动态方法也可以访问所有其他类型的私有成员和受保护成员。 这非常有用,例如,在编写代码来序列化对象时。

注意

为了向后兼容,如果以下条件都为 true,则此构造函数要求SecurityPermission使用 标志: m 是调用模块以外的模块,并且 具有 ReflectionPermissionFlag.MemberAccess 标志的 对 ReflectionPermissionSecurityPermissionFlag.ControlEvidence 的要求已失败。 如果 对 的需求 SecurityPermission 成功,则允许该操作。

另请参阅

适用于

DynamicMethod(String, Type, Type[], Type, Boolean)

Source:
DynamicMethod.cs
Source:
DynamicMethod.cs
Source:
DynamicMethod.cs

创建一个动态方法,指定方法名称、返回类型、参数类型,以及与该动态方法逻辑上相关联的类型,并指定动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员是否应跳过实时 (JIT) 可见性检查。

public:
 DynamicMethod(System::String ^ name, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, Type ^ owner, bool skipVisibility);
public DynamicMethod (string name, Type? returnType, Type[]? parameterTypes, Type owner, bool skipVisibility);
public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility);
new System.Reflection.Emit.DynamicMethod : string * Type * Type[] * Type * bool -> System.Reflection.Emit.DynamicMethod
Public Sub New (name As String, returnType As Type, parameterTypes As Type(), owner As Type, skipVisibility As Boolean)

参数

name
String

动态方法的名称。 它可以是长度为零的字符串,但不能为 null

returnType
Type

一个 Type 对象,用于指定动态方法的返回类型,如果此方法没有返回类型,则为 null

parameterTypes
Type[]

指定动态方法的参数类型的 Type 对象数组,如果此方法不具有任何参数,则为 null

owner
Type

动态方法与之在逻辑上相关联的 Type。 动态方法有权访问此类型的所有成员。

skipVisibility
Boolean

若要跳过对动态方法的 MSIL 访问的类型和成员的 JIT 可见性检查,则为 true;否则为 false

例外

parameterTypes 的元素为 nullVoid

- 或 -

owner 是一个接口、数组、开放式泛型类型,或者是泛型类型或方法的类型参数。

namenull

ownernull

.NET Framework和 .NET Core 版本早于 2.1: returnType 是返回 true的类型IsByRef

注解

使用此构造函数创建的动态方法有权访问类型 owner的所有成员,以及 Visual Basic 中的公共和 internal (Friend ,) 包含 owner的模块中所有其他类型的成员。 跳过 JIT 编译器的可见性检查,动态方法也可以访问所有其他类型的私有成员和受保护成员。 这非常有用,例如,在编写代码来序列化对象时。

此构造函数指定方法特性 MethodAttributes.PublicMethodAttributes.Static,并调用约定 CallingConventions.Standard

注意

为了向后兼容,如果以下条件都为 true,则此构造函数要求SecurityPermission使用 标志:owner位于调用模块以外的模块中,并且 具有 ReflectionPermissionFlag.MemberAccess 标志的 对 ReflectionPermissionSecurityPermissionFlag.ControlEvidence 的要求已失败。 如果 对 的需求 SecurityPermission 成功,则允许该操作。

另请参阅

适用于

DynamicMethod(String, MethodAttributes, CallingConventions, Type, Type[], Module, Boolean)

Source:
DynamicMethod.cs
Source:
DynamicMethod.cs
Source:
DynamicMethod.cs

创建一个对模块全局有效的动态方法,指定方法名称、属性、调用约定、返回类型、参数类型和模块,并指定动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员是否应跳过实时 (JIT) 可见性检查。

public:
 DynamicMethod(System::String ^ name, System::Reflection::MethodAttributes attributes, System::Reflection::CallingConventions callingConvention, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, System::Reflection::Module ^ m, bool skipVisibility);
public DynamicMethod (string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes, System.Reflection.Module m, bool skipVisibility);
public DynamicMethod (string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type returnType, Type[] parameterTypes, System.Reflection.Module m, bool skipVisibility);
new System.Reflection.Emit.DynamicMethod : string * System.Reflection.MethodAttributes * System.Reflection.CallingConventions * Type * Type[] * System.Reflection.Module * bool -> System.Reflection.Emit.DynamicMethod
Public Sub New (name As String, attributes As MethodAttributes, callingConvention As CallingConventions, returnType As Type, parameterTypes As Type(), m As Module, skipVisibility As Boolean)

参数

name
String

动态方法的名称。 它可以是长度为零的字符串,但不能为 null

attributes
MethodAttributes

用于指定动态方法属性的 MethodAttributes 值的按位组合。 允许的唯一组合为 PublicStatic

callingConvention
CallingConventions

动态方法的调用约定。 必须是 Standard

returnType
Type

一个 Type 对象,用于指定动态方法的返回类型,如果此方法没有返回类型,则为 null

parameterTypes
Type[]

指定动态方法的参数类型的 Type 对象数组,如果此方法不具有任何参数,则为 null

m
Module

一个 Module,表示动态方法将与之逻辑关联的模块。

skipVisibility
Boolean

若要跳过对动态方法的 MSIL 访问的类型和成员的 JIT 可见性检查,则为 true;否则为 false

例外

parameterTypes 的元素为 nullVoid

- 或 -

m 是为动态方法提供匿名承载的模块。

namenull

mnull

attributes 是标志的组合,而不是 PublicStatic 的组合。

- 或 -

callingConvention 不是 Standard

- 或 -

returnType 是一种 IsByRef 为其返回 true 的类型。

注解

使用此构造函数创建的动态方法可以访问 Visual Basic 中的公共和 internal (Friend ,) 模块 m中包含的所有公共和内部类型的成员。

跳过 JIT 编译器的可见性检查允许动态方法访问模块和所有其他程序集中所有其他类型的私有成员和受保护成员。 例如,编写代码以序列化对象时,这很有用。

注意

为了向后兼容,如果以下条件都为 true,则此构造函数要求SecurityPermission使用 标志:m是调用模块以外的模块,并且 具有 ReflectionPermissionFlag.MemberAccess 标志的 对 ReflectionPermissionSecurityPermissionFlag.ControlEvidence 的需求已失败。 如果 对 的需求 SecurityPermission 成功,则允许该操作。

另请参阅

适用于

DynamicMethod(String, MethodAttributes, CallingConventions, Type, Type[], Type, Boolean)

Source:
DynamicMethod.cs
Source:
DynamicMethod.cs
Source:
DynamicMethod.cs

创建一个动态方法,指定方法名称、属性、调用约定、返回类型、参数类型,以及与该动态方法逻辑上相关联的类型,并指定动态方法的 Microsoft 中间语言 (MSIL) 访问的类型和成员是否应跳过实时 (JIT) 可见性检查。

public:
 DynamicMethod(System::String ^ name, System::Reflection::MethodAttributes attributes, System::Reflection::CallingConventions callingConvention, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, Type ^ owner, bool skipVisibility);
public DynamicMethod (string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes, Type owner, bool skipVisibility);
public DynamicMethod (string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility);
new System.Reflection.Emit.DynamicMethod : string * System.Reflection.MethodAttributes * System.Reflection.CallingConventions * Type * Type[] * Type * bool -> System.Reflection.Emit.DynamicMethod
Public Sub New (name As String, attributes As MethodAttributes, callingConvention As CallingConventions, returnType As Type, parameterTypes As Type(), owner As Type, skipVisibility As Boolean)

参数

name
String

动态方法的名称。 它可以是长度为零的字符串,但不能为 null

attributes
MethodAttributes

用于指定动态方法属性的 MethodAttributes 值的按位组合。 允许的唯一组合为 PublicStatic

callingConvention
CallingConventions

动态方法的调用约定。 必须是 Standard

returnType
Type

一个 Type 对象,用于指定动态方法的返回类型,如果此方法没有返回类型,则为 null

parameterTypes
Type[]

指定动态方法的参数类型的 Type 对象数组,如果此方法不具有任何参数,则为 null

owner
Type

动态方法与之在逻辑上相关联的 Type。 动态方法有权访问此类型的所有成员。

skipVisibility
Boolean

若要跳过对动态方法的 MSIL 访问的类型和成员的 JIT 可见性检查,则为 true;否则为 false

例外

parameterTypes 的元素为 nullVoid

- 或 -

owner 是一个接口、数组、开放式泛型类型,或者是泛型类型或方法的类型参数。

namenull

ownernull

attributes 是标志的组合,而不是 PublicStatic 的组合。

- 或 -

callingConvention 不是 Standard

- 或 -

returnType 是一种 IsByRef 为其返回 true 的类型。

注解

动态方法对于包含类型 owner的模块是全局的。 它有权访问 类型 owner的所有成员。

使用此构造函数创建的动态方法有权访问类型 owner的所有成员,以及 Visual Basic 中的公共和 internal (Friend ,) 包含 的模块 owner中包含的所有类型的成员。 跳过 JIT 编译器的可见性检查允许动态方法访问所有其他类型的私有成员和受保护成员。 例如,编写代码以序列化对象时,这很有用。

注意

为了向后兼容,如果以下条件都为 true,则此构造函数要求SecurityPermission使用 标志:owner位于调用模块以外的模块中,并且 具有 ReflectionPermissionFlag.MemberAccess 标志的 对 ReflectionPermissionSecurityPermissionFlag.ControlEvidence 的需求已失败。 如果 对 的需求 SecurityPermission 成功,则允许该操作。

另请参阅

适用于