ConstructorBuilder クラス
動的クラスのコンストラクタを定義および表現します。
この型のすべてのメンバの一覧については、ConstructorBuilder メンバ を参照してください。
System.Object
System.Reflection.MemberInfo
System.Reflection.MethodBase
System.Reflection.ConstructorInfo
System.Reflection.Emit.ConstructorBuilder
NotInheritable Public Class ConstructorBuilder
Inherits ConstructorInfo
[C#]
public sealed class ConstructorBuilder : ConstructorInfo
[C++]
public __gc __sealed class ConstructorBuilder : public
ConstructorInfo
[JScript]
public class ConstructorBuilder extends ConstructorInfo
スレッドセーフ
Reflection Emit は、Boolean パラメータ isSynchronized を true に設定して呼び出した AppDomain.DefineDynamicAssembly メソッドで作成されたアセンブリを使用する場合は、スレッド セーフです。
解説
ConstructorBuilder を使用して、MSIL (Microsoft Intermediate Language) のコンストラクタを完全に記述します。名前、属性、シグネチャ、およびコンストラクタ本体が含まれます。 TypeBuilder クラスと組み合わせて使用され、実行時にクラスを作成します。 DefineConstructor を呼び出して、 ConstructorBuilder のインスタンスを取得します。
ConstructorBuilder の実際の使い方を次のコード サンプルに示します。
Imports System
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class TestCtorBuilder
Public Shared Function DynamicPointTypeGen() As Type
Dim pointType As Type = Nothing
Dim ctorParams() As Type = {GetType(Integer), GetType(Integer), GetType(Integer)}
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave)
Dim pointModule As ModuleBuilder = myAsmBuilder.DefineDynamicModule("PointModule", "Point.dll")
Dim pointTypeBld As TypeBuilder = pointModule.DefineType("Point", TypeAttributes.Public)
Dim xField As FieldBuilder = pointTypeBld.DefineField("x", GetType(Integer), FieldAttributes.Public)
Dim yField As FieldBuilder = pointTypeBld.DefineField("y", GetType(Integer), FieldAttributes.Public)
Dim zField As FieldBuilder = pointTypeBld.DefineField("z", GetType(Integer), FieldAttributes.Public)
Dim objType As Type = Type.GetType("System.Object")
Dim objCtor As ConstructorInfo = objType.GetConstructor(New Type() {})
Dim pointCtor As ConstructorBuilder = pointTypeBld.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctorParams)
Dim ctorIL As ILGenerator = pointCtor.GetILGenerator()
' NOTE: ldarg.0 holds the "this" reference - ldarg.1, ldarg.2, and ldarg.3
' hold the actual passed parameters. ldarg.0 is used by instance methods
' to hold a reference to the current calling object instance. Static methods
' do not use arg.0, since they are not instantiated and hence no reference
' is needed to distinguish them.
ctorIL.Emit(OpCodes.Ldarg_0)
' Here, we wish to create an instance of System.Object by invoking its
' constructor, as specified above.
ctorIL.Emit(OpCodes.Call, objCtor)
' Now, we'll load the current instance ref in arg 0, along
' with the value of parameter "x" stored in arg 1, into stfld.
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_1)
ctorIL.Emit(OpCodes.Stfld, xField)
' Now, we store arg 2 "y" in the current instance with stfld.
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_2)
ctorIL.Emit(OpCodes.Stfld, yField)
' Last of all, arg 3 "z" gets stored in the current instance.
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_3)
ctorIL.Emit(OpCodes.Stfld, zField)
' Our work complete, we return.
ctorIL.Emit(OpCodes.Ret)
' Now, let's create three very simple methods so we can see our fields.
Dim mthdNames() As String = {"GetX", "GetY", "GetZ"}
Dim mthdName As String
For Each mthdName In mthdNames
Dim getFieldMthd As MethodBuilder = pointTypeBld.DefineMethod(mthdName, MethodAttributes.Public, GetType(Integer), Nothing)
Dim mthdIL As ILGenerator = getFieldMthd.GetILGenerator()
mthdIL.Emit(OpCodes.Ldarg_0)
Select Case mthdName
Case "GetX"
mthdIL.Emit(OpCodes.Ldfld, xField)
Case "GetY"
mthdIL.Emit(OpCodes.Ldfld, yField)
Case "GetZ"
mthdIL.Emit(OpCodes.Ldfld, zField)
End Select
mthdIL.Emit(OpCodes.Ret)
Next mthdName
' Finally, we create the type.
pointType = pointTypeBld.CreateType()
' Let's save it, just for posterity.
myAsmBuilder.Save("Point.dll")
Return pointType
End Function 'DynamicPointTypeGen
Public Shared Sub Main()
Dim myDynamicType As Type = Nothing
Dim aPoint As Object = Nothing
Dim aPtypes() As Type = {GetType(Integer), GetType(Integer), GetType(Integer)}
Dim aPargs() As Object = {4, 5, 6}
' Call the method to build our dynamic class.
myDynamicType = DynamicPointTypeGen()
Console.WriteLine("Some information about my new Type '{0}':", myDynamicType.FullName)
Console.WriteLine("Assembly: '{0}'", myDynamicType.Assembly)
Console.WriteLine("Attributes: '{0}'", myDynamicType.Attributes)
Console.WriteLine("Module: '{0}'", myDynamicType.Module)
Console.WriteLine("Members: ")
Dim member As MemberInfo
For Each member In myDynamicType.GetMembers()
Console.WriteLine("-- {0} {1};", member.MemberType, member.Name)
Next member
Console.WriteLine("---")
' Let's take a look at the constructor we created.
Dim myDTctor As ConstructorInfo = myDynamicType.GetConstructor(aPtypes)
Console.WriteLine("Constructor: {0};", myDTctor.ToString())
Console.WriteLine("---")
' Now, we get to use our dynamically-created class by invoking the constructor.
aPoint = myDTctor.Invoke(aPargs)
Console.WriteLine("aPoint is type {0}.", aPoint.GetType())
' Finally, let's reflect on the instance of our new type - aPoint - and
' make sure everything proceeded according to plan.
Console.WriteLine("aPoint.x = {0}", myDynamicType.InvokeMember("GetX", BindingFlags.InvokeMethod, Nothing, aPoint, New Object() {}))
Console.WriteLine("aPoint.y = {0}", myDynamicType.InvokeMember("GetY", BindingFlags.InvokeMethod, Nothing, aPoint, New Object() {}))
Console.WriteLine("aPoint.z = {0}", myDynamicType.InvokeMember("GetZ", BindingFlags.InvokeMethod, Nothing, aPoint, New Object() {}))
End Sub 'Main
End Class 'TestCtorBuilder
' +++ OUTPUT +++
' Some information about my new Type 'Point':
' Assembly: 'MyDynamicAssembly, Version=0.0.0.0'
' Attributes: 'AutoLayout, AnsiClass, NotPublic, Public'
' Module: 'PointModule'
' Members:
' -- Field x;
' -- Field y;
' -- Field z;
' -- Method GetHashCode;
' -- Method Equals;
' -- Method ToString;
' -- Method GetType;
' -- Constructor .ctor;
' ---
' Constructor: Void .ctor(Int32, Int32, Int32);
' ---
' aPoint is type Point.
' aPoint.x = 4
' aPoint.y = 5
' aPoint.z = 6
[C#]
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class TestCtorBuilder {
public static Type DynamicPointTypeGen() {
Type pointType = null;
Type[] ctorParams = new Type[] {typeof(int),
typeof(int),
typeof(int)};
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder pointModule = myAsmBuilder.DefineDynamicModule("PointModule",
"Point.dll");
TypeBuilder pointTypeBld = pointModule.DefineType("Point",
TypeAttributes.Public);
FieldBuilder xField = pointTypeBld.DefineField("x", typeof(int),
FieldAttributes.Public);
FieldBuilder yField = pointTypeBld.DefineField("y", typeof(int),
FieldAttributes.Public);
FieldBuilder zField = pointTypeBld.DefineField("z", typeof(int),
FieldAttributes.Public);
Type objType = Type.GetType("System.Object");
ConstructorInfo objCtor = objType.GetConstructor(new Type[0]);
ConstructorBuilder pointCtor = pointTypeBld.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
ctorParams);
ILGenerator ctorIL = pointCtor.GetILGenerator();
// NOTE: ldarg.0 holds the "this" reference - ldarg.1, ldarg.2, and ldarg.3
// hold the actual passed parameters. ldarg.0 is used by instance methods
// to hold a reference to the current calling object instance. Static methods
// do not use arg.0, since they are not instantiated and hence no reference
// is needed to distinguish them.
ctorIL.Emit(OpCodes.Ldarg_0);
// Here, we wish to create an instance of System.Object by invoking its
// constructor, as specified above.
ctorIL.Emit(OpCodes.Call, objCtor);
// Now, we'll load the current instance ref in arg 0, along
// with the value of parameter "x" stored in arg 1, into stfld.
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_1);
ctorIL.Emit(OpCodes.Stfld, xField);
// Now, we store arg 2 "y" in the current instance with stfld.
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_2);
ctorIL.Emit(OpCodes.Stfld, yField);
// Last of all, arg 3 "z" gets stored in the current instance.
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_3);
ctorIL.Emit(OpCodes.Stfld, zField);
// Our work complete, we return.
ctorIL.Emit(OpCodes.Ret);
// Now, let's create three very simple methods so we can see our fields.
string[] mthdNames = new string[] {"GetX", "GetY", "GetZ"};
foreach (string mthdName in mthdNames) {
MethodBuilder getFieldMthd = pointTypeBld.DefineMethod(
mthdName,
MethodAttributes.Public,
typeof(int),
null);
ILGenerator mthdIL = getFieldMthd.GetILGenerator();
mthdIL.Emit(OpCodes.Ldarg_0);
switch (mthdName) {
case "GetX": mthdIL.Emit(OpCodes.Ldfld, xField);
break;
case "GetY": mthdIL.Emit(OpCodes.Ldfld, yField);
break;
case "GetZ": mthdIL.Emit(OpCodes.Ldfld, zField);
break;
}
mthdIL.Emit(OpCodes.Ret);
}
// Finally, we create the type.
pointType = pointTypeBld.CreateType();
// Let's save it, just for posterity.
myAsmBuilder.Save("Point.dll");
return pointType;
}
public static void Main() {
Type myDynamicType = null;
object aPoint = null;
Type[] aPtypes = new Type[] {typeof(int), typeof(int), typeof(int)};
object[] aPargs = new object[] {4, 5, 6};
// Call the method to build our dynamic class.
myDynamicType = DynamicPointTypeGen();
Console.WriteLine("Some information about my new Type '{0}':",
myDynamicType.FullName);
Console.WriteLine("Assembly: '{0}'", myDynamicType.Assembly);
Console.WriteLine("Attributes: '{0}'", myDynamicType.Attributes);
Console.WriteLine("Module: '{0}'", myDynamicType.Module);
Console.WriteLine("Members: ");
foreach (MemberInfo member in myDynamicType.GetMembers()) {
Console.WriteLine("-- {0} {1};", member.MemberType, member.Name);
}
Console.WriteLine("---");
// Let's take a look at the constructor we created.
ConstructorInfo myDTctor = myDynamicType.GetConstructor(aPtypes);
Console.WriteLine("Constructor: {0};", myDTctor.ToString());
Console.WriteLine("---");
// Now, we get to use our dynamically-created class by invoking the constructor.
aPoint = myDTctor.Invoke(aPargs);
Console.WriteLine("aPoint is type {0}.", aPoint.GetType());
// Finally, let's reflect on the instance of our new type - aPoint - and
// make sure everything proceeded according to plan.
Console.WriteLine("aPoint.x = {0}",
myDynamicType.InvokeMember("GetX",
BindingFlags.InvokeMethod,
null,
aPoint,
new object[0]));
Console.WriteLine("aPoint.y = {0}",
myDynamicType.InvokeMember("GetY",
BindingFlags.InvokeMethod,
null,
aPoint,
new object[0]));
Console.WriteLine("aPoint.z = {0}",
myDynamicType.InvokeMember("GetZ",
BindingFlags.InvokeMethod,
null,
aPoint,
new object[0]));
// +++ OUTPUT +++
// Some information about my new Type 'Point':
// Assembly: 'MyDynamicAssembly, Version=0.0.0.0'
// Attributes: 'AutoLayout, AnsiClass, NotPublic, Public'
// Module: 'PointModule'
// Members:
// -- Field x;
// -- Field y;
// -- Field z;
// -- Method GetHashCode;
// -- Method Equals;
// -- Method ToString;
// -- Method GetType;
// -- Constructor .ctor;
// ---
// Constructor: Void .ctor(Int32, Int32, Int32);
// ---
// aPoint is type Point.
// aPoint.x = 4
// aPoint.y = 5
// aPoint.z = 6
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type* DynamicPointTypeGen() {
Type* pointType = 0;
Type* temp0 [] = {__typeof(int),
__typeof(int),
__typeof(int)};
Type* ctorParams[] = temp0;
AppDomain* myDomain = Thread::GetDomain();
AssemblyName* myAsmName = new AssemblyName();
myAsmName->Name = S"MyDynamicAssembly";
AssemblyBuilder* myAsmBuilder = myDomain->DefineDynamicAssembly(myAsmName,
AssemblyBuilderAccess::RunAndSave);
ModuleBuilder* pointModule = myAsmBuilder->DefineDynamicModule(S"PointModule",
S"Point.dll");
TypeBuilder* pointTypeBld = pointModule->DefineType(S"Point",
TypeAttributes::Public);
FieldBuilder* xField = pointTypeBld->DefineField(S"x", __typeof(int),
FieldAttributes::Public);
FieldBuilder* yField = pointTypeBld->DefineField(S"y", __typeof(int),
FieldAttributes::Public);
FieldBuilder* zField = pointTypeBld->DefineField(S"z", __typeof(int),
FieldAttributes::Public);
Type* objType = Type::GetType(S"System.Object");
ConstructorInfo* objCtor = objType->GetConstructor(new Type*[0]);
ConstructorBuilder* pointCtor = pointTypeBld->DefineConstructor(MethodAttributes::Public,
CallingConventions::Standard,
ctorParams);
ILGenerator* ctorIL = pointCtor->GetILGenerator();
// NOTE: ldarg.0 holds the "this" reference - ldarg.1, ldarg.2, and ldarg.3
// hold the actual passed parameters. ldarg.0 is used by instance methods
// to hold a reference to the current calling bject instance. Static methods
// do not use arg.0, since they are not instantiated and hence no reference
// is needed to distinguish them.
ctorIL->Emit(OpCodes::Ldarg_0);
// Here, we wish to create an instance of System::Object by invoking its
// constructor, as specified above.
ctorIL->Emit(OpCodes::Call, objCtor);
// Now, we'll load the current instance in arg 0, along
// with the value of parameter "x" stored in arg 1, into stfld.
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Ldarg_1);
ctorIL->Emit(OpCodes::Stfld, xField);
// Now, we store arg 2 "y" in the current instance with stfld.
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Ldarg_2);
ctorIL->Emit(OpCodes::Stfld, yField);
// Last of all, arg 3 "z" gets stored in the current instance.
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Ldarg_3);
ctorIL->Emit(OpCodes::Stfld, zField);
// Our work complete, we return.
ctorIL->Emit(OpCodes::Ret);
// Now, let's create three very simple methods so we can see our fields.
String* temp1 [] = {S"GetX", S"GetY", S"GetZ"};
String* mthdNames[] = temp1;
System::Collections::IEnumerator* myEnum = mthdNames->GetEnumerator();
while (myEnum->MoveNext()) {
String* mthdName = __try_cast<String*>(myEnum->Current);
MethodBuilder* getFieldMthd = pointTypeBld->DefineMethod(mthdName,
MethodAttributes::Public,
__typeof(int),
0);
ILGenerator* mthdIL = getFieldMthd->GetILGenerator();
mthdIL->Emit(OpCodes::Ldarg_0);
if( mthdName->Equals(S"GetX") ) mthdIL->Emit(OpCodes::Ldfld, xField);
else if( mthdName->Equals(S"GetY") ) mthdIL->Emit(OpCodes::Ldfld, yField);
else if( mthdName->Equals(S"GetZ") ) mthdIL->Emit(OpCodes::Ldfld, zField);
mthdIL->Emit(OpCodes::Ret);
}
// Finally, we create the type.
pointType = pointTypeBld->CreateType();
// Let's save it, just for posterity.
myAsmBuilder->Save(S"Point.dll");
return pointType;
}
int main() {
Type* myDynamicType = 0;
Object* aPoint = 0;
Type* temp2 [] = {__typeof(int), __typeof(int), __typeof(int)};
Type* aPtypes[] = temp2;
Object* temp3 [] = {__box(4), __box(5), __box(6)};
Object* aPargs[] = temp3;
// Call the method to build our dynamic class.
myDynamicType = DynamicPointTypeGen();
Console::WriteLine(S"Some information about my new Type '{0}':",
myDynamicType->FullName);
Console::WriteLine(S"Assembly: '{0}'", myDynamicType->Assembly);
Console::WriteLine(S"Attributes: '{0}'", __box(myDynamicType->Attributes));
Console::WriteLine(S"Module: '{0}'", myDynamicType->Module);
Console::WriteLine(S"Members: ");
System::Collections::IEnumerator* myEnum = myDynamicType->GetMembers()->GetEnumerator();
while (myEnum->MoveNext()) {
MemberInfo* member = __try_cast<MemberInfo*>(myEnum->Current);
Console::WriteLine(S"-- {0} {1};", __box(member->MemberType), member->Name);
}
Console::WriteLine(S"---");
// Let's take a look at the constructor we created.
ConstructorInfo* myDTctor = myDynamicType->GetConstructor(aPtypes);
Console::WriteLine(S"Constructor: {0};", myDTctor);
Console::WriteLine(S"---");
// Now, we get to use our dynamically-created class by invoking the constructor.
aPoint = myDTctor->Invoke(aPargs);
Console::WriteLine(S"aPoint is type {0}.", aPoint->GetType());
// Finally, let's reflect on the instance of our new type - aPoint - and
// make sure everything proceeded according to plan.
Console::WriteLine(S"aPoint.x = {0}",
myDynamicType->InvokeMember(S"GetX",
BindingFlags::InvokeMethod,
0,
aPoint,
new Object*[0]));
Console::WriteLine(S"aPoint.y = {0}",
myDynamicType->InvokeMember(S"GetY",
BindingFlags::InvokeMethod,
0,
aPoint,
new Object*[0]));
Console::WriteLine(S"aPoint.z = {0}",
myDynamicType->InvokeMember(S"GetZ",
BindingFlags::InvokeMethod,
0,
aPoint,
new Object*[0]));
// +++ OUTPUT +++
// Some information about my new Type 'Point':
// Assembly: 'MyDynamicAssembly, Version=0.0.0.0'
// Attributes: 'AutoLayout, AnsiClass, NotPublic, Public'
// Module: 'PointModule'
// Members:
// -- Field x;
// -- Field y;
// -- Field z;
// -- Method GetHashCode;
// -- Method Equals;
// -- Method ToString;
// -- Method GetType;
// -- Constructor .ctor;
// ---
// Constructor: Void .ctor(Int32, Int32, Int32);
// ---
// aPoint is type Point.
// aPoint.x = 4
// aPoint.y = 5
// aPoint.z = 6
}
必要条件
名前空間: 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 内)