为什么 C# TypeBuilder.DefineConstructor 总是创建一个名为“.ctor”的构造函数?
Why C# TypeBuilder.DefineConstructor always create a Constructor named ".ctor"?
我试过这个样本。 DefineConstructor 不提供设置构造函数名称的方法。
我希望定义一个动态类型,以便我可以在 DI 容器中使用它。但是当我试图设置构造函数的方法名称时,我无法让它工作。
MethodBuilder myMethodBuilder = null;
AppDomain myCurrentDomain = AppDomain.CurrentDomain;
// Create assembly in current CurrentDomain.
AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "TempAssembly";
// Create a dynamic assembly.
myAssemblyBuilder = myCurrentDomain.DefineDynamicAssembly
(myAssemblyName, AssemblyBuilderAccess.Run);
// Create a dynamic module in the assembly.
myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("TempModule");
FieldInfo myFieldInfo =
myModuleBuilder.DefineUninitializedData("myField", 2, FieldAttributes.Public);
// Create a type in the module.
TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("TempClass",TypeAttributes.Public);
FieldBuilder myGreetingField = myTypeBuilder.DefineField("Greeting",
typeof(String), FieldAttributes.Public);
Type[] myConstructorArgs = { typeof(String) };
// Define a constructor of the dynamic class.
ConstructorBuilder myConstructor = myTypeBuilder.DefineConstructor(
MethodAttributes.Public, CallingConventions.Standard, myConstructorArgs);
// Display the name of the constructor.
Console.WriteLine("The constructor name is : "+ myConstructor.Name);
// Display the 'Type' object from which this object was obtained.
Console.WriteLine("The reflected type is : "+ myConstructor.ReflectedType);
// Display the signature of the field.
Console.WriteLine(myConstructor.Signature);
// Display the constructor builder instance as a string.
Console.WriteLine(myConstructor.ToString());
在 IL 中,构造函数没有名称,因为它们不是非常特定方式的真实函数:它们没有 return 类型。 .ctor
东西(以及 .cctor
)只是帮助您一目了然地想象它是什么,在内部它们是 类.
中的特殊条目
.ctor
是所有实例构造函数的定义名称,由 ECMA-335 定义。与另一个答案相反,它实际上是函数的名称。但是由于不能直接调用构造函数,只能通过 newobj
指令(C# 中的 new
),所以区别不大。
ECMA-335 says (我加粗):
10.5.1 Instance constructor
An instance constructor initializes an instance of a type, and is called when an instance of a type is created by the newobj
instruction (see Partition III). An instance constructor shall be an instance
(not static
or virtual
) method, it shall be named .ctor
, and marked instance
, rtspecialname
, and specialname
...
从第 22.26 节也可以清楚地看出,实际名称 .ctor
在可执行文件中进行了编码。
根据ECMA-335 II.10.5.1,构造函数必须命名为.ctor
.
An instance constructor initializes an instance of a type, and is called when an instance of a type is created by the newobj
instruction (see Partition III). An instance constructor shall be an instance (not static or virtual) method, it shall be named .ctor
[...]
您无需为构造函数指定特定名称即可通过反射调用它。给定一个 Type t
,您可以通过以下方式调用其构造函数之一:
Activator.CreateInstance(t, arg1, arg2, ...argn);
其中 arg1, arg2, ...argn
是您传递给构造函数的参数。
如果您真的想要构造函数的名称,也许是因为您需要两个具有相同签名但做不同事情的构造函数,您可以将其改为工厂方法。创建一个无参数的构造函数 使用 DefineMethod
定义一个调用该构造函数的静态方法,以某种方式设置所创建对象的某些属性,然后 returns 它。然后你可以给那个静态方法起个名字。
我试过这个样本。 DefineConstructor 不提供设置构造函数名称的方法。 我希望定义一个动态类型,以便我可以在 DI 容器中使用它。但是当我试图设置构造函数的方法名称时,我无法让它工作。
MethodBuilder myMethodBuilder = null;
AppDomain myCurrentDomain = AppDomain.CurrentDomain;
// Create assembly in current CurrentDomain.
AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "TempAssembly";
// Create a dynamic assembly.
myAssemblyBuilder = myCurrentDomain.DefineDynamicAssembly
(myAssemblyName, AssemblyBuilderAccess.Run);
// Create a dynamic module in the assembly.
myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("TempModule");
FieldInfo myFieldInfo =
myModuleBuilder.DefineUninitializedData("myField", 2, FieldAttributes.Public);
// Create a type in the module.
TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("TempClass",TypeAttributes.Public);
FieldBuilder myGreetingField = myTypeBuilder.DefineField("Greeting",
typeof(String), FieldAttributes.Public);
Type[] myConstructorArgs = { typeof(String) };
// Define a constructor of the dynamic class.
ConstructorBuilder myConstructor = myTypeBuilder.DefineConstructor(
MethodAttributes.Public, CallingConventions.Standard, myConstructorArgs);
// Display the name of the constructor.
Console.WriteLine("The constructor name is : "+ myConstructor.Name);
// Display the 'Type' object from which this object was obtained.
Console.WriteLine("The reflected type is : "+ myConstructor.ReflectedType);
// Display the signature of the field.
Console.WriteLine(myConstructor.Signature);
// Display the constructor builder instance as a string.
Console.WriteLine(myConstructor.ToString());
在 IL 中,构造函数没有名称,因为它们不是非常特定方式的真实函数:它们没有 return 类型。 .ctor
东西(以及 .cctor
)只是帮助您一目了然地想象它是什么,在内部它们是 类.
.ctor
是所有实例构造函数的定义名称,由 ECMA-335 定义。与另一个答案相反,它实际上是函数的名称。但是由于不能直接调用构造函数,只能通过 newobj
指令(C# 中的 new
),所以区别不大。
ECMA-335 says (我加粗):
10.5.1 Instance constructor
An instance constructor initializes an instance of a type, and is called when an instance of a type is created by the
newobj
instruction (see Partition III). An instance constructor shall be aninstance
(notstatic
orvirtual
) method, it shall be named.ctor
, and markedinstance
,rtspecialname
, andspecialname
...
从第 22.26 节也可以清楚地看出,实际名称 .ctor
在可执行文件中进行了编码。
根据ECMA-335 II.10.5.1,构造函数必须命名为.ctor
.
An instance constructor initializes an instance of a type, and is called when an instance of a type is created by the
newobj
instruction (see Partition III). An instance constructor shall be an instance (not static or virtual) method, it shall be named.ctor
[...]
您无需为构造函数指定特定名称即可通过反射调用它。给定一个 Type t
,您可以通过以下方式调用其构造函数之一:
Activator.CreateInstance(t, arg1, arg2, ...argn);
其中 arg1, arg2, ...argn
是您传递给构造函数的参数。
如果您真的想要构造函数的名称,也许是因为您需要两个具有相同签名但做不同事情的构造函数,您可以将其改为工厂方法。创建一个无参数的构造函数 使用 DefineMethod
定义一个调用该构造函数的静态方法,以某种方式设置所创建对象的某些属性,然后 returns 它。然后你可以给那个静态方法起个名字。