DynamicMethod 建構函式
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
建立動態方法。
多載
DynamicMethod(String, Type, Type[]) |
初始化匿名裝載的動態方法,並指定方法名稱、傳回型別和參數類型。 |
DynamicMethod(String, Type, Type[], Boolean) |
初始化匿名裝載的動態方法,並指定方法名稱、傳回類型、參數類型、以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (JIT) 可見度檢查。 |
DynamicMethod(String, Type, Type[], Module) |
建立對模組通用的動態方法,並指定方法名稱、傳回型別、參數類型和模組。 |
DynamicMethod(String, Type, Type[], Type) |
建立動態方法,指定方法名稱、傳回型別、參數類型及與動態方法在邏輯上相關聯的類型。 |
DynamicMethod(String, Type, Type[], Module, Boolean) |
建立對模組而言全域的動態方法,並指定方法名稱、傳回型別、參數類型、模組,以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (JIT) 可見度檢查。 |
DynamicMethod(String, Type, Type[], Type, Boolean) |
建立動態方法,並指定方法名稱、傳回型別、參數類型、動態方法在邏輯上相關聯的類型,以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (JIT) 可見度檢查。 |
DynamicMethod(String, MethodAttributes, CallingConventions, Type, Type[], Module, Boolean) |
建立對模組而言全域的動態方法,並指定方法名稱、屬性、呼叫慣例、傳回類型、參數類型、模組,以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (JIT) 可見度檢查。 |
DynamicMethod(String, MethodAttributes, CallingConventions, Type, Type[], Type, Boolean) |
建立動態方法、指定方法名稱、屬性、呼叫慣例、傳回類型、參數類型、動態方法在邏輯上相關聯的類型,以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (JIT) 可見度檢查。 |
DynamicMethod(String, Type, Type[])
初始化匿名裝載的動態方法,並指定方法名稱、傳回型別和參數類型。
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
。
例外狀況
parameterTypes
的項目為 null
或 Void。
name
為 null
。
.NET Framework 和 2.1 之前的 .NET Core 版本:returnType
是傳回 的IsByRef型別true
。
備註
這個建構函式所建立的動態方法會與匿名元件相關聯,而不是現有的類型或模組。 匿名元件只會提供動態方法的沙盒環境,也就是將它們與其他程式代碼隔離。 此環境可讓動態方法受到部分信任的程式代碼發出和執行的安全。
這個建構函式會指定動態方法的 Microsoft 中繼語言 (MSIL) 會強制執行 Just-In-Time (JIT) 可見性檢查。 也就是說,動態方法中的程式代碼可以存取公用類別的公用方法。 如果方法嘗試在 Visual Basic 中存取 、 private
protected
或 (Friend
的類型或internal
成員,則會擲回例外狀況) 。 若要建立能夠略過 JIT 可見度檢查的動態方法,請使用 建 DynamicMethod(String, Type, Type[], Boolean) 構函式。
建構匿名裝載的動態方法時,會包含發出元件的呼叫堆疊。 叫用 方法時,會使用發出元件的許可權,而不是實際呼叫者的許可權。 因此,動態方法無法以高於發出許可權之元件的許可權層級執行,即使傳遞至具有較高信任層級的元件並加以執行也一樣。
這個建構函式會指定 方法屬性 MethodAttributes.Public 和 MethodAttributes.Static,以及呼叫慣例 CallingConventions.Standard。
注意
此建構函式是在 .NET Framework 3.5 或更新版本中引進。
另請參閱
適用於
DynamicMethod(String, Type, Type[], Boolean)
初始化匿名裝載的動態方法,並指定方法名稱、傳回類型、參數類型、以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (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
。
- restrictedSkipVisibility
- Boolean
true
則略過對動態方法的 MSIL 所存取之類型和成員的 JIT 可視性檢查,但有此限制:包含這些類型和成員的組件的信任層級,必須等於或小於發出動態方法的呼叫堆疊的信任層級;否則為 false
。
例外狀況
parameterTypes
的項目為 null
或 Void。
name
為 null
。
.NET Framework 和 2.1 之前的 .NET Core 版本:returnType
是傳回 的IsByRef型別true
。
備註
這個建構函式所建立的動態方法會與匿名元件相關聯,而不是現有的類型或模組。 匿名元件只會提供動態方法的沙盒環境,也就是將它們與其他程式代碼隔離。 此環境可讓動態方法受到部分信任的程式代碼發出和執行的安全。
匿名裝載的動態方法無法自動存取 Visual Basic) 中任何類型或成員,private
protected
或 internal
(Friend
。 這不同於與現有類型或模組相關聯的動態方法,這些方法可以存取其相關聯範圍中的隱藏成員。
restrictedSkipVisibility
如果動態方法必須存取的類型或成員,則private
protected
指定 true
。或 internal
。 這可讓動態方法限制存取這些成員。 也就是說,只有在符合下列條件時,才能存取成員:
目標成員屬於信任層級等於或低於發出動態方法之呼叫堆疊的元件。
發出動態方法的呼叫堆疊會以旗標授 ReflectionPermission 與 ReflectionPermissionFlag.RestrictedMemberAccess 。 當程式代碼以完全信任執行時,這一定是正確的。 對於部分信任的程序代碼,只有在主機明確授與許可權時,才為 true。
重要
如果未授與許可權,則會在呼叫 或叫用動態方法時 CreateDelegate 擲回安全性例外狀況,而不是呼叫這個建構函式時。 不需要特殊許可權才能發出動態方法。
例如,如果呼叫堆疊已獲授與restrictedSkipVisibility
true
受限制的成員存取權,則建立的動態方法可以存取呼叫堆棧上任何元件的私用成員。 如果在呼叫堆疊上使用部分信任的程式代碼建立動態方法,它就無法存取 .NET Framework元件中類型的私人成員,因為這類元件完全受信任。
如果 restrictedSkipVisibility
為 false
,則會強制執行 JIT 可見度檢查。 動態方法中的程式代碼可以存取公用類別的公用方法,如果嘗試存取、 private
protected
或internal
的類型或成員,則會擲回例外狀況。
建構匿名裝載的動態方法時,會包含發出元件的呼叫堆疊。 叫用 方法時,會使用發出呼叫堆疊的許可權,而不是實際呼叫者的許可權。 因此,動態方法無法以高於發出許可權之元件的許可權層級執行,即使傳遞至具有較高信任層級的元件並加以執行也一樣。
這個建構函式會指定 方法屬性 MethodAttributes.Public 和 MethodAttributes.Static,以及呼叫慣例 CallingConventions.Standard。
注意
此建構函式是在 .NET Framework 3.5 或更新版本中引進。
另請參閱
適用於
DynamicMethod(String, Type, Type[], Module)
建立對模組通用的動態方法,並指定方法名稱、傳回型別、參數類型和模組。
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
。
例外狀況
.NET Framework 和 2.1 之前的 .NET Core 版本:returnType
是傳回 的IsByRef型別true
。
範例
下列程式代碼範例會建立採用兩個參數的動態方法。 此範例會發出簡單的函式主體,將第一個參數列印至主控台,而範例會使用第二個參數做為 方法的傳回值。 此範例會建立委派、使用不同的參數叫用委派,最後使用 方法來叫用 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.Public並MethodAttributes.Static,呼叫慣例CallingConventions.Standard,並嫄 梊-just-in-time (JIT) 可見度檢查。
使用這個建構函式建立的動態方法可以存取 Visual Basic 中公用和 internal
(Friend
,) 模組 m
中包含的所有類型成員。
注意
為了回溯相容性,如果下列條件都成立,此建構SecurityPermission函式會要求旗SecurityPermissionFlag.ControlEvidence標:m
是呼叫模組以外的模組,而且具有 ReflectionPermissionFlag.MemberAccess 旗標的需求ReflectionPermission已失敗。 如果成功要求 SecurityPermission ,則允許作業。
另請參閱
適用於
DynamicMethod(String, Type, Type[], Type)
建立動態方法,指定方法名稱、傳回型別、參數類型及與動態方法在邏輯上相關聯的類型。
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
。
例外狀況
.NET Framework 和 2.1 之前的 .NET Core 版本:returnType
是傳回 的IsByRef型別true
。
範例
下列程式代碼範例會 DynamicMethod 建立邏輯上與型別相關聯的 。 此關聯可讓其存取該類型的私用成員。
程式代碼範例會Example
使用私用字段、衍生自第一個類別的類別、名為 UseLikeStatic
DerivedFromExample
的委派型別、傳回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.Public並MethodAttributes.Static,呼叫慣例CallingConventions.Standard,並嫄 梊-just-in-time (JIT) 可見度檢查。
注意
為了回溯相容性,如果下列條件都成立,此建構SecurityPermission函式會要求旗SecurityPermissionFlag.ControlEvidence標:owner
位於呼叫模組以外的模組中,而且具有 ReflectionPermissionFlag.MemberAccess 旗標的需求ReflectionPermission已失敗。 如果成功要求 SecurityPermission ,則允許作業。
另請參閱
適用於
DynamicMethod(String, Type, Type[], Module, Boolean)
建立對模組而言全域的動態方法,並指定方法名稱、傳回型別、參數類型、模組,以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (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
。
- skipVisibility
- Boolean
true
表示要略過動態方法的 MSIL 所存取之類型和成員的 JIT 可見度檢查。
例外狀況
.NET Framework 和 2.1 之前的 .NET Core 版本:returnType
是傳回 的IsByRef型別true
。
備註
這個建構函式會指定方法的屬性MethodAttributes.Public並MethodAttributes.Static,和呼叫慣例CallingConventions.Standard。
使用這個建構函式建立的動態方法可以存取 Visual Basic 中所有類型之公用和 internal
(Friend
,) 包含模組 m
中所有類型的成員。 略過 JIT 編譯程式的可見度檢查,可讓動態方法存取所有其他類型的私人和受保護成員。 例如,撰寫程式代碼來串行化物件時,這非常有用。
注意
為了回溯相容性,如果下列條件都成立,此建構SecurityPermission函式會要求旗SecurityPermissionFlag.ControlEvidence標:m
是呼叫模組以外的模組,而且具有 ReflectionPermissionFlag.MemberAccess 旗標的需求ReflectionPermission已失敗。 如果成功要求 SecurityPermission ,則允許作業。
另請參閱
適用於
DynamicMethod(String, Type, Type[], Type, Boolean)
建立動態方法,並指定方法名稱、傳回型別、參數類型、動態方法在邏輯上相關聯的類型,以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (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
。
- skipVisibility
- Boolean
true
表示要略過動態方法的 MSIL 所存取之類型和成員的 JIT 可見度檢查,否則為 false
。
例外狀況
.NET Framework 和 2.1 之前的 .NET Core 版本:returnType
是傳回 的IsByRef型別true
。
備註
使用這個建構函式建立的動態方法可以存取 類型 owner
的所有成員,以及 Visual Basic 中公用和 internal
(Friend
的成員,) 包含 owner
之模組中所有其他類型的成員。 略過 JIT 編譯程式的可見度檢查,可讓動態方法存取所有其他類型的私人和受保護成員。 例如,撰寫程式代碼來串行化物件時,這非常有用。
這個建構函式會指定方法的屬性MethodAttributes.Public並MethodAttributes.Static,和呼叫慣例CallingConventions.Standard。
注意
為了回溯相容性,如果下列條件都成立,此建構SecurityPermission函式會要求旗SecurityPermissionFlag.ControlEvidence標:owner
位於呼叫模組以外的模組中,而且具有 ReflectionPermissionFlag.MemberAccess 旗標的需求ReflectionPermission已失敗。 如果成功要求 SecurityPermission ,則允許作業。
另請參閱
適用於
DynamicMethod(String, MethodAttributes, CallingConventions, Type, Type[], Module, Boolean)
建立對模組而言全域的動態方法,並指定方法名稱、屬性、呼叫慣例、傳回類型、參數類型、模組,以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (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 值的位元組合。 唯一允許的組合是 Public 和 Static。
- callingConvention
- CallingConventions
動態方法的的呼叫慣例。 必須是 Standard。
- skipVisibility
- Boolean
true
表示要略過動態方法的 MSIL 所存取之類型和成員的 JIT 可見度檢查,否則為 false
。
例外狀況
attributes
是 Public 和 Static 以外的旗標組合。
-或-
callingConvention
不是 Standard。
-或-
returnType
類型是 IsByRef 傳回 true
的對象。
備註
使用此建構函式建立的動態方法可以存取 Visual Basic 中公用和 internal
(Friend
,) 模組 m
中包含的所有公用和內部類型成員。
略過 JIT 編譯程式的可見性檢查,可讓動態方法存取模組和所有其他元件中所有其他類型的私人和受保護成員。 例如,撰寫程式代碼以串行化物件時,這非常有用。
注意
為了回溯相容性,如果下列條件同時為 true,此建構SecurityPermission函式會要求 旗SecurityPermissionFlag.ControlEvidence標:m
是呼叫模組以外的模組,且具有 ReflectionPermissionFlag.MemberAccess 旗標的需求ReflectionPermission失敗。
SecurityPermission如果 要求成功,則允許此作業。
另請參閱
適用於
DynamicMethod(String, MethodAttributes, CallingConventions, Type, Type[], Type, Boolean)
建立動態方法、指定方法名稱、屬性、呼叫慣例、傳回類型、參數類型、動態方法在邏輯上相關聯的類型,以及是否應該略過動態方法的 Microsoft Intermediate Language (MSIL) 所存取之類型和成員的 Just-In-Time (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 值的位元組合。 唯一允許的組合是 Public 和 Static。
- callingConvention
- CallingConventions
動態方法的的呼叫慣例。 必須是 Standard。
- skipVisibility
- Boolean
true
表示要略過動態方法的 MSIL 所存取之類型和成員的 JIT 可見度檢查,否則為 false
。
例外狀況
attributes
是 Public 和 Static 以外的旗標組合。
-或-
callingConvention
不是 Standard。
-或-
returnType
類型是 IsByRef 傳回 true
的對象。
備註
動態方法是包含 型 owner
別的模組全域方法。 它可以存取類型 owner
的所有成員。
使用這個建構函式建立的動態方法可以存取類型 owner
的所有成員,以及Visual Basic中公用和 internal
(Friend
) 包含之模組 owner
中所有類型的成員。 略過 JIT 編譯程式的可見性檢查,可讓動態方法存取所有其他類型的私人和受保護成員。 例如,撰寫程式代碼以串行化物件時,這非常有用。
注意
為了回溯相容性,如果下列條件同時為 true,此建構SecurityPermission函式會要求 旗SecurityPermissionFlag.ControlEvidence標:owner
位於呼叫模組以外的模組中,且具有 ReflectionPermissionFlag.MemberAccess 旗標的需求ReflectionPermission失敗。
SecurityPermission如果 要求成功,則允許此作業。