45 votes

Quel est le type de retour d'un constructeur en C# ?

J'ai posé cette question à Java sur este lien

J'ai obtenu quelques réponses en Java et je voudrais maintenant savoir ce qu'il en est en C#.

Comme nous le savons, il n'est pas nécessaire d'ajouter un type de retour à un constructeur C#.

class Sample{
  .....
  Sample(){
    ........
  }
}

En Objective C, si l'on crée un constructeur, celui-ci renvoie un pointeur sur sa classe. Mais ce n'est pas obligatoire, je pense.

AClass *anObject = [[AClass alloc] init];//init is the constructor with return type a pointer to AClass

De même, le constructeur est-il converti en une méthode qui renvoie une référence à sa propre classe ?

Comme ceci :

class Sample{
    .....
    Sample Sample(){
      ........

      return this;
    }
}

Est-ce que le compilateur ajoute un type de retour une référence à la même classe au constructeur ? Que se passe-t-il dans un constructeur ? Y a-t-il une référence pour étudier cela ?

47voto

InBetween Points 6162

Selon la Spécification du langage C# 4.0 , section 1.6 :

Les instances des classes sont créées à l'aide de la fonction new qui alloue de la mémoire pour une nouvelle instance, invoque un constructeur pour initialiser l'instance et renvoie une référence à l'instance.

Il s'agit de la new qui est responsable de l'allocation de la mémoire, de la transmission d'une référence de l'objet nouvellement alloué au constructeur et du renvoi d'une référence à l'instance. Ce mécanisme est également expliqué à la section 7.6.10.1 :

Le traitement en cours d'exécution d'un expression de création d'objet o new T(A) donde T es type de classe ou un type de structure y A i liste d'arguments Il se compose des étapes suivantes :

  • Si T es un type de classe :

    • Une nouvelle instance de la classe T est allouée. S'il n'y a pas assez de mémoire disponible pour allouer le nouvel inst System.OutOfMemoryException est rejeté et aucune autre mesure n'est prise. exécutées.

    • Tous les champs de la nouvelle instance sont initialisés à leur valeur par défaut. (§5.2).

    • Le constructeur de l'instance est i règles d'invocation des membres de fonctions (§7.5.4). Une référence à l'instance allouée est automatiquement passée au constructeur d'instance et l'instance peut être accédée à partir de ce constructeur sous la forme this .

  • [ ]

Cela signifie que le constructeur en soi n'a pas de type de retour ( void ).

19voto

afrischke Points 2763

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.

4voto

Jon Hanna Points 40291

Cela dépend de la façon dont on voit les choses.

Le "type de retour" est aussi conceptuel qu'autre chose.

Au niveau de la sémantique dans laquelle C# exprime l'intention du programmeur, les constructeurs n'ont pas de type de retour. Ils n'ont même pas de void . Ils n'ont pas plus de type de retour que vous.

L'IL dans lequel ces constructeurs seront compilés a un type de retour de void .

Si vous invoquez un ConstructorInfo vous obtenez un objet du type en question (bien que le type de retour de cette invocation soit object et vous devez effectuer un cast vers le type concerné).

Ce qui se rapproche le plus d'une signification concrète du retour, ce sont les détails de la manipulation de la pile par le constructeur appelé. Dans ce cas, on pourrait dire que si un type de référence "renvoie" une référence du type approprié, puisqu'il place la valeur dans la pile, un type de valeur ne le fait pas, puisqu'il manipule les valeurs déjà présentes sur la pile. Ou vous pourriez simplement affirmer que les deux sont des détails d'implémentation et qu'ils ne répondent pas vraiment à la question.

"N'a pas de type de retour" est probablement la façon la plus "C#" de considérer la question.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X