DynamicMethod クラス
アセンブリ: mscorlib (mscorlib.dll 内)


DynamicMethod クラスを使用すると、実行時にメソッドを生成し実行できます。メソッドを格納するために、動的アセンブリと動的型を生成する必要はありません。動的メソッドは、少量のコードを生成し実行するための最も効率的な方法です。
動的メソッドは、モジュールまたは型に論理的に関連付けられます。動的メソッドがモジュールに関連付けられている場合、そのモジュールに対して実質的にはグローバルです。十分なアクセス許可があれば、動的メソッドはジャスト イン タイム (JIT: Just-In-Time) の参照範囲チェックをスキップし、そのモジュール内で宣言されている型のプライベート データにアクセスできます。開発者がそのモジュールを作成したかどうかに関係なく、動的メソッドはどのモジュールにでも関連付けることができます。
動的メソッドが型に関連付けられている場合、その型のプライベート メンバにアクセスできます。動的メソッドが同じモジュール内で宣言されている他の型のプライベート データにアクセスしない場合は、JIT の参照範囲チェックをスキップする必要はありません。動的メソッドは、どの型にも関連付けることができます。
モジュールまたはモジュール内の型に関連付けられた動的メソッドについて、JIT の参照範囲チェックを行う場合およびスキップする場合に、動的メソッドにアクセス可能なモジュール内の型のメンバを次の表に示します。
| ||
動的メソッドは、関連付けられているモジュール、または関連付けられている型を格納するモジュールのアクセス許可を持ちます。
動的メソッドとそのパラメータには、名前を付ける必要はありませんが、名前を指定するとデバッグを行う際に役立ちます。動的メソッドまたはそのパラメータでは、カスタム属性はサポートされていません。
動的メソッドは static メソッド (Visual Basic では Shared メソッド) ですが、.NET Framework Version 2.0 に導入されているデリゲート バインディングの緩やかな規則では、動的メソッドをオブジェクトにバインドすることが許可されています。したがって、そのデリゲート インスタンスを使用して動的メソッドを呼び出した場合、インスタンス メソッドと同様に機能します。この例については、CreateDelegate(Type,Object) メソッド オーバーロードで説明しています。

2 つのパラメータを使用する動的メソッドを作成するコード例を次に示します。この例では、コンソールに 1 つ目のパラメータを出力する簡単な関数本体を出力し、2 つ目のパラメータをメソッドの戻り値として使用しています。この例では、デリゲートを作成することによってメソッドを完了し、さまざまなパラメータを持つデリゲートを呼び出し、最後に Invoke メソッドを使用して動的メソッドを呼び出します。
Imports System Imports System.Reflection Imports System.Reflection.Emit Imports Microsoft.VisualBasic Imports System.Globalization Public Class Test ' Declare a delegate type that can be used to execute the completed ' dynamic method. Private Delegate Function HelloDelegate(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 dynamic 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 String class. Dim hello As New DynamicMethod("Hello", _ GetType(Integer), _ helloArgs, _ GetType(String).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 , ' 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) ' Display MethodAttributes for the dynamic method, set when ' the dynamic method was created. Console.WriteLine(vbCrLf & "Method Attributes: {0}", _ hello.Attributes) ' Display the calling convention of the dynamic method, set when the ' dynamic method was created. Console.WriteLine(vbCrLf & "Calling convention: {0}", _ hello.CallingConvention) ' Display the declaring type, which is always Nothing for dynamic ' methods. If hello.DeclaringType Is Nothing Then Console.WriteLine(vbCrLf & "DeclaringType is always Nothing for dynamic methods.") Else Console.WriteLine("DeclaringType: {0}", hello.DeclaringType) End If ' Display the default value for InitLocals. If hello.InitLocals Then Console.Write(vbCrLf & "This method contains verifiable code.") Else Console.Write(vbCrLf & "This method contains unverifiable code.") End If Console.WriteLine(" (InitLocals = {0})", hello.InitLocals) ' Display the module specified when the dynamic method was created. Console.WriteLine(vbCrLf & "Module: {0}", hello.Module) ' Display the name specified when the dynamic method was created. ' Note that the name can be blank. Console.WriteLine(vbCrLf & "Name: {0}", hello.Name) ' For dynamic methods, the reflected type is always Nothing. If hello.ReflectedType Is Nothing Then Console.WriteLine(vbCrLf & "ReflectedType is Nothing.") Else Console.WriteLine(vbCrLf & "ReflectedType: {0}", _ hello.ReflectedType) End If If hello.ReturnParameter Is Nothing Then Console.WriteLine(vbCrLf & "Method has no return parameter.") Else Console.WriteLine(vbCrLf & "Return parameter: {0}", _ hello.ReturnParameter) End If ' If the method has no return type, ReturnType is System.Void. Console.WriteLine(vbCrLf & "Return type: {0}", hello.ReturnType) ' ReturnTypeCustomAttributes returns an ICustomeAttributeProvider ' 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 Is GetType(System.Void) Then Console.WriteLine("The method has no return type.") Else Dim caProvider As ICustomAttributeProvider = _ hello.ReturnTypeCustomAttributes Dim returnAttributes() As Object = _ caProvider.GetCustomAttributes(True) If returnAttributes.Length = 0 Then Console.WriteLine(vbCrLf _ & "The return type has no custom attributes.") Else Console.WriteLine(vbCrLf _ & "The return type has the following custom attributes:") For Each attr As Object In returnAttributes Console.WriteLine(vbTab & attr.ToString()) Next attr End If End If Console.WriteLine(vbCrLf & "ToString: " & hello.ToString()) ' 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. Dim parameter1 As ParameterBuilder = hello.DefineParameter( _ 1, ParameterAttributes.In, "message") Dim parameter2 As ParameterBuilder = hello.DefineParameter( _ 2, ParameterAttributes.In, "valueToReturn") ' Display parameter information. Dim parameters() As ParameterInfo = hello.GetParameters() Console.WriteLine(vbCrLf & "Parameters: name, type, ParameterAttributes") For Each p As ParameterInfo In parameters Console.WriteLine(vbTab & "{0}, {1}, {2}", _ p.Name, p.ParameterType, p.Attributes) Next p ' 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 HelloDelegate = _ CType(hello.CreateDelegate(GetType(HelloDelegate)), HelloDelegate) ' Use the delegate to execute the dynamic method. Console.WriteLine(vbCrLf & "Use the delegate to execute the dynamic method:") Dim retval As Integer = hi(vbCrLf & "Hello, World!", 42) Console.WriteLine("Invoking delegate hi(""Hello, World!"", 42) returned: " _ & retval & ".") ' Execute it again, with different arguments. retval = hi(vbCrLf & "Hi, Mom!", 5280) Console.WriteLine("Invoking delegate hi(""Hi, Mom!"", 5280) returned: " _ & retval & ".") Console.WriteLine(vbCrLf & "Use the Invoke method to execute the dynamic method:") ' 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 value-type arguments ' must be boxed. Dim objRet As Object = hello.Invoke(Nothing, _ BindingFlags.ExactBinding, Nothing, invokeArgs, _ New CultureInfo("en-us")) Console.WriteLine("hello.Invoke returned: {0}", objRet) End Sub End Class ' This code example produces the following output: ' 'Method Attributes: PrivateScope, Public, Static ' 'Calling convention: Standard ' 'DeclaringType is always Nothing for dynamic methods. ' 'This method contains verifiable code. (InitLocals = True) ' 'Module: CommonLanguageRuntimeLibrary ' 'Name: Hello ' 'ReflectedType is Nothing. ' 'Method has no return parameter. ' 'Return type: System.Int32 ' 'The return type has no custom attributes. ' 'ToString: Int32 Hello(System.String, Int32) ' 'Parameters: name, type, ParameterAttributes ' message, System.String, In ' valueToReturn, System.Int32, In ' 'Use the delegate to execute the dynamic method: ' 'Hello, World! 'Invoking delegate hi("Hello, World!", 42) returned: 42. ' 'Hi, Mom! 'Invoking delegate hi("Hi, Mom!", 5280) returned: 5280. ' 'Use the Invoke method to execute the dynamic method: ' 'Hello, World! 'hello.Invoke returned: 42
using System; using System.Reflection; using System.Reflection.Emit; using System.Globalization; public class Test { // Declare a delegate type that can be used to execute the completed // dynamic method. private delegate int HelloDelegate(string msg, int ret); public static void Main() { // Create an array that specifies the types of the parameters // of the dynamic method. This dynamic method has a String // parameter and an Integer parameter. Type[] helloArgs = {typeof(string), typeof(int)}; // 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 String class. DynamicMethod hello = new DynamicMethod("Hello", typeof(int), helloArgs, typeof(string).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 , // 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); // Display MethodAttributes for the dynamic method, set when // the dynamic method was created. Console.WriteLine("\r\nMethod Attributes: {0}", hello.Attributes); // Display the calling convention of the dynamic method, set when the // dynamic method was created. Console.WriteLine("\r\nCalling convention: {0}", hello.CallingConvention); // 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); } // 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); // Display the module specified when the dynamic method was created. Console.WriteLine("\r\nModule: {0}", hello.Module); // Display the name specified when the dynamic method was created. // Note that the name can be blank. Console.WriteLine("\r\nName: {0}", hello.Name); // 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); } if (hello.ReturnParameter==null) { Console.WriteLine("\r\nMethod has no return parameter."); } else { Console.WriteLine("\r\nReturn parameter: {0}", hello.ReturnParameter); } // If the method has no return type, ReturnType is System.Void. Console.WriteLine("\r\nReturn type: {0}", hello.ReturnType); // ReturnTypeCustomAttributes returns an ICustomeAttributeProvider // 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()); } } } Console.WriteLine("\r\nToString: {0}", hello.ToString()); // 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. ParameterBuilder parameter1 = hello.DefineParameter( 1, ParameterAttributes.In, "message" ); ParameterBuilder parameter2 = hello.DefineParameter( 2, ParameterAttributes.In, "valueToReturn" ); // 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); } // 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. 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); 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 CultureInfo("en-us")); Console.WriteLine("hello.Invoke returned: " + objRet); } } /* This code example produces the following output: Method Attributes: PrivateScope, Public, Static Calling convention: Standard DeclaringType is always null for dynamic methods. This method contains verifiable code. (InitLocals = True) Module: CommonLanguageRuntimeLibrary Name: Hello ReflectedType is null. Method has no return parameter. Return type: System.Int32 The return type has no custom attributes. ToString: Int32 Hello(System.String, Int32) Parameters: name, type, ParameterAttributes message, System.String, In valueToReturn, System.Int32, In Use the delegate to execute the dynamic method: Hello, World! Invoking delegate hi("Hello, World!", 42) returned: 42 Hi, Mom! Invoking delegate hi("Hi, Mom!", 5280) returned: 5280 Use the Invoke method to execute the dynamic method: Hello, World! hello.Invoke returned: 42 */

System.Reflection.MemberInfo
System.Reflection.MethodBase
System.Reflection.MethodInfo
System.Reflection.Emit.DynamicMethod


Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


- DynamicMethod クラスのページへのリンク