为什么 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 它。然后你可以给那个静态方法起个名字。