MethodBuilder 类
定义并表示动态类的方法(或构造函数)。
**命名空间:**System.Reflection.Emit
**程序集:**mscorlib(在 mscorlib.dll 中)
语法
声明
<ClassInterfaceAttribute(ClassInterfaceType.None)> _
<ComVisibleAttribute(True)> _
Public NotInheritable Class MethodBuilder
Inherits MethodInfo
Implements _MethodBuilder
用法
Dim instance As MethodBuilder
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComVisibleAttribute(true)]
public sealed class MethodBuilder : MethodInfo, _MethodBuilder
[ClassInterfaceAttribute(ClassInterfaceType::None)]
[ComVisibleAttribute(true)]
public ref class MethodBuilder sealed : public MethodInfo, _MethodBuilder
/** @attribute ClassInterfaceAttribute(ClassInterfaceType.None) */
/** @attribute ComVisibleAttribute(true) */
public final class MethodBuilder extends MethodInfo implements _MethodBuilder
ClassInterfaceAttribute(ClassInterfaceType.None)
ComVisibleAttribute(true)
public final class MethodBuilder extends MethodInfo implements _MethodBuilder
备注
提示
应用于此类的 HostProtectionAttribute 属性 (Attribute) 具有以下 Resources 属性 (Property) 值:MayLeakOnAbort。HostProtectionAttribute 并不会影响桌面应用程序(桌面应用程序通常通过双击图标、键入命令或在浏览器中输入 URL 来启动)。有关更多信息,请参见 HostProtectionAttribute 类或 SQL Server 编程和宿主保护属性。
MethodBuilder 用于充分描述 Microsoft 中间语言 (MSIL) 中的方法,包括名称、属性、签名和方法体。它与 TypeBuilder 类一起使用以在运行时创建类。
示例
下面提供一个示例,演示如何使用 MethodBuilder 类在动态类型中创建一个方法。
Imports System
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DemoMethodBuilder
Public Shared Sub AddMethodDynamically(ByRef myTypeBld As TypeBuilder, _
mthdName As String, _
mthdParams() As Type, _
returnType As Type, _
mthdAction As String)
Dim myMthdBld As MethodBuilder = myTypeBld.DefineMethod(mthdName, _
MethodAttributes.Public Or MethodAttributes.Static, _
returnType, _
mthdParams)
Dim ILout As ILGenerator = myMthdBld.GetILGenerator()
Dim numParams As Integer = mthdParams.Length
Dim x As Byte
For x = 0 To numParams - 1
ILout.Emit(OpCodes.Ldarg_S, x)
Next x
If numParams > 1 Then
Dim y As Integer
For y = 0 To (numParams - 1) - 1
Select Case mthdAction
Case "A"
ILout.Emit(OpCodes.Add)
Case "M"
ILout.Emit(OpCodes.Mul)
Case Else
ILout.Emit(OpCodes.Add)
End Select
Next y
End If
ILout.Emit(OpCodes.Ret)
End Sub 'AddMethodDynamically
Public Shared Sub Main()
Dim myDomain As AppDomain = Thread.GetDomain()
Dim asmName As New AssemblyName()
asmName.Name = "DynamicAssembly1"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(asmName, _
AssemblyBuilderAccess.RunAndSave)
Dim myModule As ModuleBuilder = myAsmBuilder.DefineDynamicModule("DynamicModule1", _
"MyDynamicAsm.dll")
Dim myTypeBld As TypeBuilder = myModule.DefineType("MyDynamicType", TypeAttributes.Public)
' Get info from the user to build the method dynamically.
Console.WriteLine("Let's build a simple method dynamically!")
Console.WriteLine("Please enter a few numbers, separated by spaces.")
Dim inputNums As String = Console.ReadLine()
Console.Write("Do you want to [A]dd or [M]ultiply these numbers? ")
Dim myMthdAction As String = Console.ReadLine()
Console.Write("Lastly, what do you want to name your new dynamic method? ")
Dim myMthdName As String = Console.ReadLine()
' Process inputNums into an array and create a corresponding Type array
Dim index As Integer = 0
Dim inputNumsList As String() = inputNums.Split()
Dim myMthdParams(inputNumsList.Length - 1) As Type
Dim inputValsList(inputNumsList.Length - 1) As Object
Dim inputNum As String
For Each inputNum In inputNumsList
inputValsList(index) = CType(Convert.ToInt32(inputNum), Object)
myMthdParams(index) = GetType(Integer)
index += 1
Next inputNum
' Now, call the method building method with the parameters, passing the
' TypeBuilder by reference.
AddMethodDynamically(myTypeBld, myMthdName, myMthdParams, GetType(Integer), myMthdAction)
Dim myType As Type = myTypeBld.CreateType()
Dim description as String
If myMthdAction = "A" Then
description = "adding"
Else
description = "multiplying"
End If
Console.WriteLine("---")
Console.WriteLine("The result of {0} the inputted values is: {1}", _
description, _
myType.InvokeMember(myMthdName, _
BindingFlags.InvokeMethod Or _
BindingFlags.Public Or _
BindingFlags.Static, _
Nothing, _
Nothing, _
inputValsList))
Console.WriteLine("---")
' If you are interested in seeing the MSIL generated dynamically for the method
' your program generated, change to the directory where you ran the compiled
' code sample and type "ildasm MyDynamicAsm.dll" at the prompt. When the list
' of manifest contents appears, click on "MyDynamicType" and then on the name of
' of the method you provided during execution.
myAsmBuilder.Save("MyDynamicAsm.dll")
Dim myMthdInfo As MethodInfo = myType.GetMethod(myMthdName)
Console.WriteLine("Your Dynamic Method: {0};", myMthdInfo.ToString())
End Sub 'Main
End Class 'DemoMethodBuilder
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DemoMethodBuilder {
public static void AddMethodDynamically (ref TypeBuilder myTypeBld,
string mthdName,
Type[] mthdParams,
Type returnType,
string mthdAction)
{
MethodBuilder myMthdBld = myTypeBld.DefineMethod(
mthdName,
MethodAttributes.Public |
MethodAttributes.Static,
returnType,
mthdParams);
ILGenerator ILout = myMthdBld.GetILGenerator();
int numParams = mthdParams.Length;
for (byte x=0; x<numParams; x++) {
ILout.Emit(OpCodes.Ldarg_S, x);
}
if (numParams > 1) {
for (int y=0; y<(numParams-1); y++) {
switch (mthdAction) {
case "A": ILout.Emit(OpCodes.Add);
break;
case "M": ILout.Emit(OpCodes.Mul);
break;
default: ILout.Emit(OpCodes.Add);
break;
}
}
}
ILout.Emit(OpCodes.Ret);
}
public static void Main()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName asmName = new AssemblyName();
asmName.Name = "DynamicAssembly1";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
asmName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder myModule = myAsmBuilder.DefineDynamicModule("DynamicModule1",
"MyDynamicAsm.dll");
TypeBuilder myTypeBld = myModule.DefineType("MyDynamicType",
TypeAttributes.Public);
// Get info from the user to build the method dynamically.
Console.WriteLine("Let's build a simple method dynamically!");
Console.WriteLine("Please enter a few numbers, separated by spaces.");
string inputNums = Console.ReadLine();
Console.Write("Do you want to [A]dd or [M]ultiply these numbers? ");
string myMthdAction = Console.ReadLine();
Console.Write("Lastly, what do you want to name your new dynamic method? ");
string myMthdName = Console.ReadLine();
// Process inputNums into an array and create a corresponding Type array
int index = 0;
string[] inputNumsList = inputNums.Split();
Type[] myMthdParams = new Type[inputNumsList.Length];
object[] inputValsList = new object[inputNumsList.Length];
foreach (string inputNum in inputNumsList) {
inputValsList[index] = (object)Convert.ToInt32(inputNum);
myMthdParams[index] = typeof(int);
index++;
}
// Now, call the method building method with the parameters, passing the
// TypeBuilder by reference.
AddMethodDynamically(ref myTypeBld,
myMthdName,
myMthdParams,
typeof(int),
myMthdAction);
Type myType = myTypeBld.CreateType();
Console.WriteLine("---");
Console.WriteLine("The result of {0} the inputted values is: {1}",
((myMthdAction == "A") ? "adding" : "multiplying"),
myType.InvokeMember(myMthdName,
BindingFlags.InvokeMethod | BindingFlags.Public |
BindingFlags.Static,
null,
null,
inputValsList));
Console.WriteLine("---");
// Let's take a look at the method we created.
// If you are interested in seeing the MSIL generated dynamically for the method
// your program generated, change to the directory where you ran the compiled
// code sample and type "ildasm MyDynamicAsm.dll" at the prompt. When the list
// of manifest contents appears, click on "MyDynamicType" and then on the name of
// of the method you provided during execution.
myAsmBuilder.Save("MyDynamicAsm.dll");
MethodInfo myMthdInfo = myType.GetMethod(myMthdName);
Console.WriteLine("Your Dynamic Method: {0};", myMthdInfo.ToString());
}
}
using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
void AddMethodDynamically( TypeBuilder^ myTypeBld, String^ mthdName, array<Type^>^mthdParams, Type^ returnType, String^ mthdAction )
{
MethodBuilder^ myMthdBld = myTypeBld->DefineMethod( mthdName, static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), returnType, mthdParams );
ILGenerator^ ILOut = myMthdBld->GetILGenerator();
int numParams = mthdParams->Length;
for ( Byte x = 0; x < numParams; x++ )
{
ILOut->Emit( OpCodes::Ldarg_S, x );
}
if ( numParams > 1 )
{
for ( int y = 0; y < (numParams - 1); y++ )
{
if ( mthdAction->Equals( "A" ) )
ILOut->Emit( OpCodes::Add );
else
if ( mthdAction->Equals( "M" ) )
ILOut->Emit( OpCodes::Mul );
else
ILOut->Emit( OpCodes::Mul );
}
}
ILOut->Emit( OpCodes::Ret );
}
int main()
{
AppDomain^ myDomain = Thread::GetDomain();
AssemblyName^ asmName = gcnew AssemblyName;
asmName->Name = "DynamicAssembly1";
AssemblyBuilder^ myAsmBuilder = myDomain->DefineDynamicAssembly( asmName, AssemblyBuilderAccess::RunAndSave );
ModuleBuilder^ myModule = myAsmBuilder->DefineDynamicModule( "DynamicModule1", "MyDynamicAsm.dll" );
TypeBuilder^ myTypeBld = myModule->DefineType( "MyDynamicType", TypeAttributes::Public );
// Get info from the user to build the method dynamically.
Console::WriteLine( "Let's build a simple method dynamically!" );
Console::WriteLine( "Please enter a few numbers, separated by spaces." );
String^ inputNums = Console::ReadLine();
Console::Write( "Do you want to [A]dd or [M]ultiply these numbers? " );
String^ myMthdAction = Console::ReadLine();
Console::Write( "Lastly, what do you want to name your new dynamic method? " );
String^ myMthdName = Console::ReadLine();
// Process inputNums into an array and create a corresponding Type array
int index = 0;
array<String^>^inputNumsList = inputNums->Split( 0 );
array<Type^>^myMthdParams = gcnew array<Type^>(inputNumsList->Length);
array<Object^>^inputValsList = gcnew array<Object^>(inputNumsList->Length);
System::Collections::IEnumerator^ myEnum = inputNumsList->GetEnumerator();
while ( myEnum->MoveNext() )
{
String^ inputNum = safe_cast<String^>(myEnum->Current);
inputValsList[ index ] = Convert::ToInt32( inputNum );
myMthdParams[ index ] = int::typeid;
index++;
}
// Now, call the method building method with the parameters, passing the
// TypeBuilder by reference.
AddMethodDynamically( myTypeBld, myMthdName, myMthdParams, int::typeid, myMthdAction );
Type^ myType = myTypeBld->CreateType();
Console::WriteLine( "---" );
Console::WriteLine( "The result of {0} the inputted values is: {1}", ((myMthdAction->Equals( "A" )) ? (String^)"adding" : "multiplying"), myType->InvokeMember( myMthdName, static_cast<BindingFlags>(BindingFlags::InvokeMethod | BindingFlags::Public | BindingFlags::Static), nullptr, nullptr, inputValsList ) );
Console::WriteLine( "---" );
// Let's take a look at the method we created.
// If you are interested in seeing the MSIL generated dynamically for the method
// your program generated, change to the directory where you ran the compiled
// code sample and type "ildasm MyDynamicAsm.dll" at the prompt. When the list
// of manifest contents appears, click on "MyDynamicType" and then on the name of
// of the method you provided during execution.
myAsmBuilder->Save( "MyDynamicAsm.dll" );
MethodInfo^ myMthdInfo = myType->GetMethod( myMthdName );
Console::WriteLine( "Your Dynamic Method: {0};", myMthdInfo );
}
import System.*;
import System.Threading.*;
import System.Reflection.*;
import System.Reflection.Emit.*;
class DemoMethodBuilder
{
public static void AddMethodDynamically(TypeBuilder myTypeBld,
String mthdName, Type mthdParams[], Type returnType, String mthdAction)
{
MethodBuilder myMthdBld = myTypeBld.DefineMethod(mthdName,
MethodAttributes.Public | MethodAttributes.Static,
returnType, mthdParams);
ILGenerator iLout = myMthdBld.GetILGenerator();
int numParams = mthdParams.length;
for (ubyte x = 0; x < numParams; x++) {
iLout.Emit(OpCodes.Ldarg_S, x);
}
if (numParams > 1) {
for (int y = 0; y < numParams - 1; y++) {
if (mthdAction.Equals("A") == true) {
iLout.Emit(OpCodes.Add);
}
else if (mthdAction.Equals("M") == true) {
iLout.Emit(OpCodes.Mul);
}
else {
iLout.Emit(OpCodes.Add);
}
}
}
iLout.Emit(OpCodes.Ret);
} //AddMethodDynamically
public static void main(String[] args)
{
AppDomain myDomain = System.Threading.Thread.GetDomain();
AssemblyName asmName = new AssemblyName();
asmName.set_Name("DynamicAssembly1");
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(asmName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder myModule = myAsmBuilder.DefineDynamicModule
("DynamicModule1", "MyDynamicAsm.dll");
TypeBuilder myTypeBld = myModule.DefineType("MyDynamicType",
TypeAttributes.Public);
// Get info from the user to build the method dynamically.
Console.WriteLine("Let's build a simple method dynamically!");
Console.WriteLine("Please enter a few numbers, separated by spaces.");
String inputNums = Console.ReadLine();
Console.Write("Do you want to [A]dd or [M]ultiply these numbers? ");
String myMthdAction = Console.ReadLine();
Console.Write("Lastly, what do you want to name your new "
+ "dynamic method? ");
String myMthdName = Console.ReadLine();
// Process inputNums into an array and create a corresponding
// Type array
int index = 0;
String inputNumsList[] = inputNums.Split(null);
Type myMthdParams[] = new Type[inputNumsList.length];
Object inputValsList[] = new Object[inputNumsList.length];
for (int iCtr = 0; iCtr < inputNumsList.length; iCtr++) {
String inputNum = inputNumsList[iCtr];
inputValsList[index] = (Object)(Int32)Integer.parseInt(inputNum);
myMthdParams.set_Item(index, int.class.ToType());
index++;
}
// Now, call the method building method with the parameters,
// passing the TypeBuilder by reference.
AddMethodDynamically(myTypeBld, myMthdName, myMthdParams,
int.class.ToType(), myMthdAction);
Type myType = myTypeBld.CreateType();
Console.WriteLine("---");
Console.WriteLine("The result of {0} the inputted values is: {1}",
(myMthdAction.equals("A")) ? "adding" : "multiplying",
myType.InvokeMember(myMthdName,
BindingFlags.InvokeMethod | BindingFlags.Public |
BindingFlags.Static, null, null, inputValsList));
Console.WriteLine("---");
// Let's take a look at the method we created.
// If you are interested in seeing the MSIL generated dynamically for
// the method your program generated, change to the directory where
// you ran the compiled code sample and type "ildasm MyDynamicAsm.dll"
// at the prompt. When the list of manifest contents appears, click on
// "MyDynamicType" and then on the name of the method you provided
// during execution.
myAsmBuilder.Save("MyDynamicAsm.dll");
MethodInfo myMthdInfo = myType.GetMethod(myMthdName);
Console.WriteLine("Your Dynamic Method: {0};", myMthdInfo.ToString());
} //main
} //DemoMethodBuilder
继承层次结构
System.Object
System.Reflection.MemberInfo
System.Reflection.MethodBase
System.Reflection.MethodInfo
System.Reflection.Emit.MethodBuilder
线程安全
此类型的任何公共静态(Visual Basic 中的 Shared)成员都是线程安全的,但不保证所有实例成员都是线程安全的。
平台
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 并不是对每个平台的所有版本都提供支持。有关受支持版本的列表,请参见系统要求。
版本信息
.NET Framework
受以下版本支持:2.0、1.1、1.0