ParameterBuilder クラス
パラメータ情報の作成または関連付けを行います。
この型のすべてのメンバの一覧については、ParameterBuilder メンバ を参照してください。
System.Object
System.Reflection.Emit.ParameterBuilder
Public Class ParameterBuilder
[C#]
public class ParameterBuilder
[C++]
public __gc class ParameterBuilder
[JScript]
public class ParameterBuilder
スレッドセーフ
Reflection Emit は、Boolean パラメータ isSynchronized を true に設定して呼び出した AppDomain.DefineDynamicAssembly メソッドで作成されたアセンブリを使用する場合は、スレッド セーフです。
解説
パラメータ属性は、メソッド シグネチャと矛盾しないようにする必要があります。パラメータに Out 属性を指定する場合は、そのメソッド パラメータの型を ByRef 型にする必要があります。 ParameterBuilder 属性を使用する場合、属性によっては、MSIL (Microsoft Intermediate Language) が実行時に正しく動作するように有効なパラメータで DefineMethod を呼び出す必要があります。たとえば、 MethodBuilder のパラメータ 1 に ParameterAttributes.Out を使用して ParameterBuilder を定義する場合、 MethodBuilder のパラメータ 1 は、Type.GetType("System.String") ではなく、Type.GetType("System.String&") のような参照にする必要があります。
使用例
[Visual Basic, C#, C++] ParameterBuilder を使用して参照を渡すパラメータを持つ動的メソッドを作成する方法を次の例に示します。
Imports System
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class ParamBuilderDemo
Public Shared Function BuildCustomerDataType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyMod")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("CustomerData", TypeAttributes.Public)
Dim customerNameBldr As FieldBuilder = myTypeBuilder.DefineField("customerName", _
GetType(String), _
FieldAttributes.Private)
Dim acctIDBldr As FieldBuilder = myTypeBuilder.DefineField("acctID", _
GetType(String), _
FieldAttributes.Private)
Dim balanceAmtBldr As FieldBuilder = myTypeBuilder.DefineField("balanceAmt", _
GetType(Double), _
FieldAttributes.Private)
Dim myCtorBuilder As ConstructorBuilder = myTypeBuilder.DefineConstructor(MethodAttributes.Public, _
CallingConventions.HasThis, _
New Type() {GetType(String), _
GetType(String), _
GetType(Double)})
Dim ctorIL As ILGenerator = myCtorBuilder.GetILGenerator()
Dim objType As Type = Type.GetType("System.Object")
Dim objCtor As ConstructorInfo = objType.GetConstructor(New Type(){})
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Call, objCtor)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_1)
ctorIL.Emit(OpCodes.Stfld, customerNameBldr)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_2)
ctorIL.Emit(OpCodes.Stfld, acctIDBldr)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_3)
ctorIL.Emit(OpCodes.Stfld, balanceAmtBldr)
ctorIL.Emit(OpCodes.Ret)
' This method will take an amount from a static pool and add it to the balance.
' Note that we are passing the first parameter, fundsPool, by reference. Therefore,
' we need to inform the MethodBuilder to expect a ref, by declaring the first
' parameter's type to be System.Double& (a reference to a double).
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("AddFundsFromPool", _
MethodAttributes.Public, _
GetType(Double), _
New Type() {Type.GetType("System.Double&"), _
GetType(Double)})
Dim poolRefBuilder As ParameterBuilder = myMthdBuilder.DefineParameter(1, _
ParameterAttributes.Out, "fundsPool")
Dim amountFromPoolBuilder As ParameterBuilder = myMthdBuilder.DefineParameter(2, _
ParameterAttributes.In, "amountFromPool")
Dim mthdIL As ILGenerator = myMthdBuilder.GetILGenerator()
mthdIL.Emit(OpCodes.Ldarg_1)
mthdIL.Emit(OpCodes.Ldarg_1)
mthdIL.Emit(OpCodes.Ldind_R8)
mthdIL.Emit(OpCodes.Ldarg_2)
mthdIL.Emit(OpCodes.Sub)
mthdIL.Emit(OpCodes.Stind_R8)
mthdIL.Emit(OpCodes.Ldarg_0)
mthdIL.Emit(OpCodes.Ldarg_0)
mthdIL.Emit(OpCodes.Ldfld, balanceAmtBldr)
mthdIL.Emit(OpCodes.Ldarg_2)
mthdIL.Emit(OpCodes.Add)
mthdIL.Emit(OpCodes.Stfld, balanceAmtBldr)
mthdIL.Emit(OpCodes.Ldarg_0)
mthdIL.Emit(OpCodes.Ldfld, balanceAmtBldr)
mthdIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildCustomerDataType
Public Shared Sub Main()
Dim custType As Type = Nothing
Dim custObj As Object = Nothing
Dim custArgTypes() As Type = {GetType(String), GetType(String), GetType(Double)}
' Call the method to build our dynamic class.
custType = BuildCustomerDataType()
Console.WriteLine("---")
Dim myCustCtor As ConstructorInfo = custType.GetConstructor(custArgTypes)
Dim initialBalance As Double = 100.0
custObj = myCustCtor.Invoke(New Object() {"Joe Consumer", "5678-XYZ", initialBalance})
Dim myMemberInfo As MemberInfo() = custType.GetMember("AddFundsFromPool")
Dim thePool As Double = 1000.0
Console.WriteLine("The pool is currently ${0}", thePool)
Console.WriteLine("The original balance of the account instance is ${0}", initialBalance)
Dim amountFromPool As Double = 50.0
Console.WriteLine("The amount to be subtracted from the pool and added " & _
"to the account is ${0}", amountFromPool)
Console.WriteLine("---")
Console.WriteLine("Calling {0} ...", myMemberInfo(0).ToString())
Console.WriteLine("---")
Dim passMe() As Object = {thePool, amountFromPool}
Console.WriteLine("The new balance in the account instance is ${0}", _
custType.InvokeMember("AddFundsFromPool", _
BindingFlags.InvokeMethod, Nothing, custObj, passMe))
thePool = CDbl(passMe(0))
Console.WriteLine("The new amount in the pool is ${0}", thePool)
End Sub 'Main
End Class 'ParamBuilderDemo
[C#]
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class ParamBuilderDemo
{
public static Type BuildCustomerDataType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule("MyMod");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("CustomerData",
TypeAttributes.Public);
FieldBuilder customerNameBldr = myTypeBuilder.DefineField("customerName",
typeof(string),
FieldAttributes.Private);
FieldBuilder acctIDBldr = myTypeBuilder.DefineField("acctID",
typeof(string),
FieldAttributes.Private);
FieldBuilder balanceAmtBldr = myTypeBuilder.DefineField("balanceAmt",
typeof(double),
FieldAttributes.Private);
ConstructorBuilder myCtorBuilder = myTypeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.HasThis,
new Type[] { typeof(string),
typeof(string),
typeof(double) });
ILGenerator ctorIL = myCtorBuilder.GetILGenerator();
Type objType = Type.GetType("System.Object");
ConstructorInfo objCtor = objType.GetConstructor(new Type[] {});
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Call, objCtor);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_1);
ctorIL.Emit(OpCodes.Stfld, customerNameBldr);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_2);
ctorIL.Emit(OpCodes.Stfld, acctIDBldr);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_3);
ctorIL.Emit(OpCodes.Stfld, balanceAmtBldr);
ctorIL.Emit(OpCodes.Ret);
// This method will take an amount from a static pool and add it to the balance.
// Note that we are passing the first parameter, fundsPool, by reference. Therefore,
// we need to inform the MethodBuilder to expect a ref, by declaring the first
// parameter's type to be System.Double& (a reference to a double).
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("AddFundsFromPool",
MethodAttributes.Public,
typeof(double),
new Type[] { Type.GetType("System.Double&"),
typeof(double) });
ParameterBuilder poolRefBuilder = myMthdBuilder.DefineParameter(1,
ParameterAttributes.Out,
"fundsPool");
ParameterBuilder amountFromPoolBuilder = myMthdBuilder.DefineParameter(2,
ParameterAttributes.In,
"amountFromPool");
ILGenerator mthdIL = myMthdBuilder.GetILGenerator();
mthdIL.Emit(OpCodes.Ldarg_1);
mthdIL.Emit(OpCodes.Ldarg_1);
mthdIL.Emit(OpCodes.Ldind_R8);
mthdIL.Emit(OpCodes.Ldarg_2);
mthdIL.Emit(OpCodes.Sub);
mthdIL.Emit(OpCodes.Stind_R8);
mthdIL.Emit(OpCodes.Ldarg_0);
mthdIL.Emit(OpCodes.Ldarg_0);
mthdIL.Emit(OpCodes.Ldfld, balanceAmtBldr);
mthdIL.Emit(OpCodes.Ldarg_2);
mthdIL.Emit(OpCodes.Add);
mthdIL.Emit(OpCodes.Stfld, balanceAmtBldr);
mthdIL.Emit(OpCodes.Ldarg_0);
mthdIL.Emit(OpCodes.Ldfld, balanceAmtBldr);
mthdIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type custType = null;
object custObj = null;
Type[] custArgTypes = new Type[] {typeof(string), typeof(string), typeof(double)};
// Call the method to build our dynamic class.
custType = BuildCustomerDataType();
Console.WriteLine("---");
ConstructorInfo myCustCtor = custType.GetConstructor(custArgTypes);
double initialBalance = 100.00;
custObj = myCustCtor.Invoke(new object[] { "Joe Consumer",
"5678-XYZ",
initialBalance });
MemberInfo[] myMemberInfo = custType.GetMember("AddFundsFromPool");
double thePool = 1000.00;
Console.WriteLine("The pool is currently ${0}", thePool);
Console.WriteLine("The original balance of the account instance is ${0}",
initialBalance);
double amountFromPool = 50.00;
Console.WriteLine("The amount to be subtracted from the pool and added " +
"to the account is ${0}", amountFromPool);
Console.WriteLine("---");
Console.WriteLine("Calling {0} ...", myMemberInfo[0].ToString());
Console.WriteLine("---");
object[] passMe = new object[] { thePool, amountFromPool };
Console.WriteLine("The new balance in the account instance is ${0}",
custType.InvokeMember("AddFundsFromPool",
BindingFlags.InvokeMethod,
null, custObj, passMe));
thePool = (double)passMe[0];
Console.WriteLine("The new amount in the pool is ${0}", thePool);
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type* BuildCustomerDataType() {
AppDomain* myDomain = Thread::GetDomain();
AssemblyName* myAsmName = new AssemblyName();
myAsmName->Name = S"MyDynamicAssembly";
AssemblyBuilder* myAsmBuilder = myDomain->DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess::Run);
ModuleBuilder* myModBuilder = myAsmBuilder->DefineDynamicModule(S"MyMod");
TypeBuilder* myTypeBuilder = myModBuilder->DefineType(
S"CustomerData",
TypeAttributes::Public);
FieldBuilder* customerNameBldr = myTypeBuilder->DefineField(
S"customerName",
__typeof(String),
FieldAttributes::Private);
FieldBuilder* acctIDBldr = myTypeBuilder->DefineField(
S"acctID",
__typeof(String),
FieldAttributes::Private);
FieldBuilder* balanceAmtBldr = myTypeBuilder->DefineField(
S"balanceAmt",
__typeof(double),
FieldAttributes::Private);
Type* temp0 [] = {__typeof(String), __typeof(String), __typeof(double)};
ConstructorBuilder* myCtorBuilder = myTypeBuilder->DefineConstructor(
MethodAttributes::Public,
CallingConventions::HasThis,
temp0);
ILGenerator* ctorIL = myCtorBuilder->GetILGenerator();
Type* objType = Type::GetType(S"System.Object");
ConstructorInfo* objCtor = objType->GetConstructor(new Type*[0]);
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Call, objCtor);
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Ldarg_1);
ctorIL->Emit(OpCodes::Stfld, customerNameBldr);
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Ldarg_2);
ctorIL->Emit(OpCodes::Stfld, acctIDBldr);
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Ldarg_3);
ctorIL->Emit(OpCodes::Stfld, balanceAmtBldr);
ctorIL->Emit(OpCodes::Ret);
// This method will take an amount from a static pool and add it to the balance.
// Note that we are passing the first parameter, fundsPool, by reference. Therefore,
// we need to inform the MethodBuilder to expect a ref, by declaring the first
// parameter's type to be System::Double& (a reference to a double).
Type* temp4 [] = {Type::GetType(S"System.Double&"), __typeof(double)};
MethodBuilder* myMthdBuilder = myTypeBuilder->DefineMethod(
S"AddFundsFromPool",
MethodAttributes::Public,
__typeof(double),
temp4);
ParameterBuilder* poolRefBuilder = myMthdBuilder->DefineParameter(
1,
ParameterAttributes::Out,
S"fundsPool");
ParameterBuilder* amountFromPoolBuilder = myMthdBuilder->DefineParameter(
2,
ParameterAttributes::In,
S"amountFromPool");
ILGenerator* mthdIL = myMthdBuilder->GetILGenerator();
mthdIL->Emit(OpCodes::Ldarg_1);
mthdIL->Emit(OpCodes::Ldarg_1);
mthdIL->Emit(OpCodes::Ldind_R8);
mthdIL->Emit(OpCodes::Ldarg_2);
mthdIL->Emit(OpCodes::Sub);
mthdIL->Emit(OpCodes::Stind_R8);
mthdIL->Emit(OpCodes::Ldarg_0);
mthdIL->Emit(OpCodes::Ldarg_0);
mthdIL->Emit(OpCodes::Ldfld, balanceAmtBldr);
mthdIL->Emit(OpCodes::Ldarg_2);
mthdIL->Emit(OpCodes::Add);
mthdIL->Emit(OpCodes::Stfld, balanceAmtBldr);
mthdIL->Emit(OpCodes::Ldarg_0);
mthdIL->Emit(OpCodes::Ldfld, balanceAmtBldr);
mthdIL->Emit(OpCodes::Ret);
return myTypeBuilder->CreateType();
}
int main() {
Type* custType = 0;
Object* custObj = 0;
Type* custArgTypes[] = {__typeof(String), __typeof(String), __typeof(double)};
// Call the method to build our dynamic class.
custType = BuildCustomerDataType();
Console::WriteLine(S"---");
ConstructorInfo* myCustCtor = custType->GetConstructor(custArgTypes);
double initialBalance = 100.00;
Object* temp5 [] = {S"Joe Consumer", S"5678-XYZ", __box(initialBalance)};
custObj = myCustCtor->Invoke(temp5);
MemberInfo* myMemberInfo[] = custType->GetMember(S"AddFundsFromPool");
double thePool = 1000.00;
Console::WriteLine(S"The pool is currently ${0}", __box(thePool));
Console::WriteLine(S"The original balance of the account instance is ${0}", __box(initialBalance));
double amountFromPool = 50.00;
Console::WriteLine(S"The amount to be subtracted from the pool and added to the account is ${0}", __box(amountFromPool));
Console::WriteLine(S"---");
Console::WriteLine(S"Calling {0} ...", myMemberInfo[0]);
Console::WriteLine(S"---");
Object* passMe[] = { __box(thePool), __box(amountFromPool) };
Console::WriteLine(S"The new balance in the account instance is ${0}",
custType->InvokeMember(S"AddFundsFromPool",
BindingFlags::InvokeMethod,
0, custObj, passMe));
thePool = *dynamic_cast<double __gc *>(passMe[0]);
Console::WriteLine(S"The new amount in the pool is ${0}", __box(thePool));
}
[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン をクリックします。
必要条件
名前空間: System.Reflection.Emit
プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ
アセンブリ: Mscorlib (Mscorlib.dll 内)