Home > Blockchain >  Why C# TypeBuilder.DefineConstructor always create a Constructor named ".ctor"?
Why C# TypeBuilder.DefineConstructor always create a Constructor named ".ctor"?

Time:03-12

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

CodePudding user response:

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.

CodePudding user response:

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

CodePudding user response:

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.

  • Related