La réponse d'InBetween est correcte. Je ne suis pas non plus d'accord avec ce qui a été discuté dans le forum MSDN. Si nous regardons un exemple de code très simple comme celui ci-dessous :
void Main()
{
var a = new A();
var message = a.GetAs();
}
public class A {
private readonly string someAs;
public A()
{
someAs = "AaaaaAAAAAaaAAAAAAAaa";
return;
}
public String GetAs()
{
return someAs;
}
}
et l'IL correspondant :
IL_0000: newobj UserQuery+A..ctor
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: callvirt UserQuery+A.GetMessage
A.GetMessage:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery+A.someAs
IL_0006: ret
A..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ldarg.0
IL_0007: ldstr "AaaaaAAAAAaaAAAAAAAaa"
IL_000C: stfld UserQuery+A.someAs
IL_0011: ret
alors il devient immédiatement clair que le .ctor renvoie void
. (Ceci peut également être vu facilement si vous essayer pour renvoyer quelque chose du constructeur, c'est-à-dire si vous faites quelque chose comme public A() { return this; }
le compilateur se plaindra et dira quelque chose comme "Puisque A() retourne void, un mot-clé return ne doit pas être suivi d'une expression d'objet").
Plus loin : Vous pouvez constater que cette expression new A()
est traduit par l'IL suivant : newobj UserQuery+A..ctor
. Le "Common Language Infrastructure Reference" indique ce qui suit à propos de newobj
(section 4.20) :
L'instruction newobj alloue une nouvelle instance de la classe associée au constructeur et initialise tous les champs de la nouvelle instance à 0 (du type approprié) ou à null, selon le cas. Elle appelle ensuite le constructeur avec les arguments donnés et l'instance nouvellement créée. Après l'appel du constructeur, la référence de l'objet maintenant initialisé est poussée sur la pile.
(A titre de comparaison avec l'Objective-C : new/newobj est l'analogue de la fonction alloc
et le constructeur l'analogue du message init
message.)
Il s'agit donc bien de la new
qui renvoie une référence à l'objet nouvellement construit, et non au constructeur lui-même.