2
votes

Struct a-t-il un constructeur par défaut?

J'ai lu quelque part que l'utilisation de new pour instancier une struct attribue des valeurs par défaut à toutes les variables de l'instance. Cela implique-t-il qu'une structure aura ses valeurs initialisées via un constructeur masqué par défaut?


0 commentaires

4 Réponses :


2
votes

Cela implique-t-il qu'une structure aura ses valeurs initialisées via un constructeur masqué par défaut?

Oui, dans le sens où tous les champs membres seront définis sur leurs valeurs par défaut (T) .

En pratique, le compilateur pourrait simplement faire quelque chose comme memset (ptr, 0, sizeInBytes) . Ce qui se passe réellement est un détail de mise en œuvre.


2 commentaires

Que se passe-t-il lorsque vous ignorez le nouveau mot-clé?


Le compilateur traitera tous les champs publics comme non attribués. Vous devrez les définir un par un. Lorsque vous avez des propriétés, la structure sera inutilisable.



0
votes

Struct ne peut pas avoir de constructeur sans paramètre et pour initialiser vos valeurs, vous devez écrire un constructeur avec des paramètres et l'appeler explicitement lors de l'initialisation de l'objet et vous devez initialiser tous les champs, et par défaut si vous n'avez pas spécifié de constructeur, toutes les valeurs seront initialisées à leurs valeurs par défaut comme vous l'avez dit avec une valeur invisible. Remarque: le CLR permet à Structs d'avoir un constructeur sans paramètre en langage IL par exemple.


0 commentaires

0
votes

Chaque type d'emplacement de stockage dans .NET qui occupe N octets a une valeur par défaut, dont la représentation est une séquence de N octets initialisée à zéro. La valeur par défaut d'un type de référence quelconque se comportera comme une référence nulle, la valeur par défaut de tout type numérique se comportera comme le nombre zéro et la valeur par défaut d'un type de structure se comportera comme une instance dont les membres ont tous des types par défaut. L'emplacement de stockage est initialisé à la valeur par défaut lorsque l'objet qui contient est créé; le seul aspect du type d'emplacement de stockage qui est pertinent pour le processus est sa taille. Si un type de structure Foo a une longueur de 16 octets et qu'une classe a un champ de type Foo , la création d'une instance de cette classe réservera 16 octets pour la structure et les initialisera à zéro, sans appeler aucun type de constructeur pour cette structure.

Notez que si une structure a un constructeur sans paramètre, il y a des circonstances dans lesquelles la création d'une instance invoquera ce constructeur, mais beaucoup dans lesquelles la création d'un emplacement de stockage créera effectivement une instance sans appeler le constructeur. Parce qu'il n'est pas toujours clair quel traitement serait applicable dans quelles situations, certains concepteurs de langage ont décidé d'esquiver le problème en interdisant simplement la définition de constructeurs sans paramètre et en supposant qu'aucune structure ne les aura (ignorant la possibilité de constructeurs sans paramètre déclarés dans d'autres langages ).


3 commentaires

Implicite dans votre explication: Une struct créée par le compilateur C # n'a pas un tel constructeur d'instance sans paramètre. Donc, ce dernier paragraphe n'est pas pertinent pour une telle structure.


@JeppeStigNielsen: Je n'ai pas suivi l'évolution du C #. Je sais qu'il a été question d'autoriser les constructeurs de structures sans paramètre, mais je ne sais pas si quelque chose est devenu de ceux-ci. Personnellement, je n'aime pas l'idée que les concepteurs de langage décident à quelles fonctionnalités de la plate-forme sous-jacente les programmeurs sont autorisés à accéder, en particulier pour les langages comme C # qui sont censés être "universels". Je pense que c'est ironique, par exemple, que la gestion des exceptions vb.net ait été pendant des années sémantiquement supérieure à celle de C # car elle pourrait [quoique maladroitement] avoir une clause finally ...


... se comportent différemment selon que la clause try s'est terminée normalement, sans avoir à intercepter l'exception À mon humble avis, le modèle approprié de gestion des exceptions dans la plupart des cas devrait être qu'une exception imprévue qui se produit alors qu'un objet pourrait être dans un état invalide devrait le laisser dans un état expressément invalidé, mais la présence d'un code qui invalide l'objet ne devrait pas l'exception à considérer comme "gérée".



0
votes

Ma "solution de contournement" pour utiliser des structures avec un constructeur sans paramètre

struct MyStruc
{
    // MyStruc( int NoOp = 0 ) did not work. The code was not called until a parameter was passed in. 
    public MyStruc( int NoOp )
    {
       MyFooBar = new FooBar()
    }

    public FooBar MyFooBar;
}

public class Main
{
    // Implementation
    public MyStruc ms = new MyStruct(0);
}


0 commentaires