为什么 C# TypeBuilder.DefineConstructor 总是创建一个名为“.ctor”的构造函数?

发布于 2025-01-13 22:33:22 字数 1662 浏览 11 评论 0原文

我尝试了这个样本。 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());

I tried this sample. DefineConstructor does not provide a way to set Constructor name.
I wish to define a dynamic type so I can use it in DI container. But I cannot Get it work when I am trying to set a method name of constructor.


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());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月静好 2025-01-20 22:33:22

根据 ECMA-335 II.10.5。 1、构造函数必须命名为.ctor

实例构造函数初始化类型的实例,并在由 newobj 指令创建类型的实例时调用(请参阅分区 III)。实例构造函数应该是一个实例(不是静态或虚拟)方法,它应该被命名为 .ctor [...]

您不需要为构造函数命名一个特定的名称来调用它与反思。给定一个 Type t,您可以通过以下方式调用其构造函数之一:

Activator.CreateInstance(t, arg1, arg2, ...argn);

其中 arg1、arg2、...argn 是传递给构造函数的参数。

如果您确实想要为构造函数命名,也许是因为您需要两个具有相同签名但执行不同操作的构造函数,则可以将其改为工厂方法。创建无参数构造函数 使用 DefineMethod 定义一个调用该构造函数的静态方法,以某种方式设置所创建对象的某些属性,然后返回它。然后您可以为该静态方法命名。

According to ECMA-335 II.10.5.1, constructors must be named .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 [...]

You don't need to name the constructor a specific name in order to call it with reflection. Given a Type t, you can call one of its constructors by:

Activator.CreateInstance(t, arg1, arg2, ...argn);

where arg1, arg2, ...argn are the arguments you pass to the constructor.

If you really want a name for your constructor, perhaps because you need two constructors that have the same signature but does different things, you can make it a factory method instead. Make a parameterless constructor Use DefineMethod to define a static method that calls that constructor, sets some properties of the created object in some way, and returns it. Then you can give a name to that static method.

長街聽風 2025-01-20 22:33:22

在 IL 中,构造函数没有名称,因为它们在特定方面不是真正的函数:它们没有返回类型。 .ctor 事物(以及 .cctor)只是帮助您一目了然地可视化它是什么,在内部它们是类中的特殊条目。

In IL, constructors don't have names, because they're not real functions in a very specific way: they don't have a return type. The .ctor thing (as well as .cctor) is just something to help you visualize what it is at a glance, internally they're special entries in classes.

泪之魂 2025-01-20 22:33:22

.ctor 是所有实例构造函数的定义名称,由 ECMA-335 定义。与其他答案相反,它实际上是函数的名称。但由于构造函数不能直接调用,只能通过 newobj 指令(C# 中的 new)调用,所以区别不大。

ECMA-335 说(我的粗体)

10.5.1 实例构造函数

实例构造函数初始化类型的实例,并在由 newobj 指令创建类型的实例时调用(请参阅分区 III)。实例构造函数应是实例(不是静态虚拟)方法,它应命名为.ctor,并标记为instancertspecialnamespecialname...


从第22.26节中也可以清楚地看出,实际的名称 .ctor 被编码在可执行文件中。

.ctor is the defined name of all instance constructors, as defined by ECMA-335. Contrary to the other answer, it is actually the name of the function. But being that constructors cannot be called directly, only via a newobj instruction (new in C#) it makes little difference.

ECMA-335 says (my bold):

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...

It is also clear from section 22.26, that the actual name .ctor is encoded in the executable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文