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 aninstance
(notstatic
orvirtual
) method, it shall be named.ctor
, and markedinstance
,rtspecialname
, andspecialname
...
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.