DynamicMethod.GetILGenerator 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
傳回可以用來發出動態方法之主體的 MSIL 產生器。
多載
GetILGenerator(Int32) |
針對方法,傳回具有指定 Microsoft Intermediate Language (MSIL) 資料流大小的 MSIL 產生器。 |
GetILGenerator() |
針對方法,傳回具有預設 Microsoft Intermediate Language (MSIL) 資料流大小 64 位元組的 MSIL 產生器。 |
GetILGenerator(Int32)
針對方法,傳回具有指定 Microsoft Intermediate Language (MSIL) 資料流大小的 MSIL 產生器。
public:
System::Reflection::Emit::ILGenerator ^ GetILGenerator(int streamSize);
public System.Reflection.Emit.ILGenerator GetILGenerator (int streamSize);
member this.GetILGenerator : int -> System.Reflection.Emit.ILGenerator
Public Function GetILGenerator (streamSize As Integer) As ILGenerator
參數
- streamSize
- Int32
MSIL 資料流的大小,以位元組為單位。
傳回
方法的 ILGenerator 物件,具有指定的 MSIL 資料流大小。
範例
下列程式代碼範例示範這個方法多載。 此程式代碼範例是針對 類別提供的較大範例的 DynamicMethod 一部分。
// 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,
// 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, nullptr);
// 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 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);
' 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,
' using a stream size larger than the IL that will be
' emitted.
Dim il As ILGenerator = 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, 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)
備註
在動態方法完成之後,藉由呼叫 CreateDelegate 或 Invoke 方法,會忽略任何進一步嘗試新增 MSIL。 不會擲回任何例外狀況。
注意
動態方法中無法驗證的程式代碼有一些限制,即使在某些完全信任的案例中也是如此。 如需了解 DynamicMethod,請參閱<備註>中的<驗證>一節。
另請參閱
適用於
GetILGenerator()
針對方法,傳回具有預設 Microsoft Intermediate Language (MSIL) 資料流大小 64 位元組的 MSIL 產生器。
public:
System::Reflection::Emit::ILGenerator ^ GetILGenerator();
public System.Reflection.Emit.ILGenerator GetILGenerator ();
member this.GetILGenerator : unit -> System.Reflection.Emit.ILGenerator
Public Function GetILGenerator () As ILGenerator
傳回
方法的 ILGenerator 物件。
範例
下列程式代碼範例會建立採用兩個參數的動態方法。 此範例會發出簡單的函式主體,將第一個參數列印至主控台,而範例會使用第二個參數做為 方法的傳回值。 此範例會建立委派、使用不同的參數叫用委派,最後使用 方法來叫用 Invoke 動態方法。
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
'
備註
在動態方法完成之後,藉由呼叫 CreateDelegate 或 Invoke 方法,會忽略任何進一步嘗試新增 MSIL。 不會擲回任何例外狀況。
注意
動態方法中無法驗證的程式代碼有一些限制,即使在某些完全信任的案例中也是如此。 如需了解 DynamicMethod,請參閱<備註>中的<驗證>一節。