J'ai lu toutes les questions relatives à ce sujet et ils donnent tous des raisons pour lesquelles un constructeur par défaut sur un La solution évidente consiste simplement à convertir simplement le Y a-t-il d'autres options pour le garder en tant que J'ai couru dans cette situation avec l'un de nos objets d'API de commerce internes. Le concepteur le convertit à partir d'un Je pensais que si nous allons garder l'objet comme un Edit: J'aimerais voir quelques suggestions sur la manière de conserver ce type d'objet sous forme de struct code> n'est pas disponible en C #, mais je n'ai trouvé personne qui suggère un cours général d'action lorsqu'elle est confrontée à cette situation. P>
struct code> à une classe
code> et gérer les conséquences. P>
struct code>? p>
classe code> à un
struct code>, et maintenant le constructeur par défaut (qui était privé avant) laisse l'objet dans un état invalide. P>
struct code>, un mécanisme de vérification de la validité de l'état doit être introduit (quelque chose comme un
isvalid code> propriété). J'ai été rencontré avec beaucoup de résistance et une explication de "quiconque utilise l'API ne doit pas utiliser le constructeur par défaut", un commentaire qui a certainement levé mes sourcils. (Remarque: L'objet en question est construit «correctement» via des méthodes d'usine statiques, et tous les autres constructeurs sont
internes code>.) P>
struct code> s sur
classe code> es dans cette situation sans une seconde pensée? strong> p> p>
struct code> - L'objet en question ci-dessus est beaucoup mieux adapté à un
struct code > que comme une classe
code>. p>
3 Réponses :
La raison en est qu'une structure (une instance de système.valueType) est traitée spécialement par le CLR: il est initialisé avec tous les champs étant 0 (ou par défaut). Vous n'avez même pas vraiment besoin de créer un - juste le déclarer. C'est pourquoi les constructeurs par défaillants sont requis. P>
Vous pouvez contourner cela de deux manières: p>
Modification de la structure à une classe peut avoir des conséquences très subtiles (en termes d'utilisation de la mémoire et d'identité d'objet qui mènent davantage dans un environnement multithread), et non si subtile mais difficile à déboguer NullReferenceExceptions pour des objets non initialisés. < / p>
pour un Mes suggestions: P>
struct code>, vous concevez le type de l'instance construite par défaut (champs tout zéro) est un état valide. Vous ne devez pas em>] utiliser arbitrairement utiliser
struct code> au lieu de
Classe code> sans bonne raison - il n'y a rien de mal à utiliser un type de référence immuable. p>
struct code> est valide (un profileur [réel] a révélé des problèmes de performances significatifs résultant d'une lourde attribution d'un objet très léger). LI>
struct code> en dehors de l'emballage (type imbriqué privé). De cette façon, vous pouvez facilement documenter et vérifier l'utilisation correcte des exigences de type contraint. LI>
ul>
Bonne réponse. Un peu, pour mon cas particulier ci-dessus, aucun de ce que vous avez dit ne s'applique, car des problèmes sont plus facilement introduits dans le code lorsque l'objet est un type de référence ... Par conséquent, pourquoi il a été converti en structure. Mais dans de nombreux autres cas, l'utilisation d'un type de référence immuable serait une solution viable.
La raison pour laquelle il n'est pas possible de définir un constructeur par défaut est illustré par l'expression suivante: Vous avez 3 options ici p> .NET fait la même chose pour les structures et les classes: les champs et les éléments de tableau sont bloqués avec des zéros. Cela obtient également un comportement plus cohérent entre les structs et les classes et aucun code dangereux. Il permet également à la framework .NET de ne pas spécialiser quelque chose comme et c'est le constructeur par défaut pour les exigences de Structs .NET et prend soin de lui-même: zéro. Tous les octets. P> Maintenant, pour gérer cela, vous avez quelques options: p>
nouvel octet [1000] code>. P>
hasvalue code> sur
nullable code>). li>
c'est une excellente question. Vous pouvez concevoir une structure de telle sorte que l'état à zéro est valide, mais cela seul ne fera pas toujours pour une API utilisable. Si le constructeur par défaut est présent, certaines personnes l'appellent inévitablement car elles apparaîtront dans leur IDE et fourniront le chemin du moindre résistance. Et cela conduira à des problèmes que le compilateur devrait attraper, ou ils perdront du temps à essayer de définir des propriétés sur une structure à zéro immuable. Je souhaite que c # vous a permis de masquer le constructeur par défaut et des personnes forcées d'appeler par défaut (...) si elles veulent vraiment une structure à zéro.
En réalité, recherchez cela plus, je pense que la question de la convivialité est vraiment d'intellensense plutôt que du compilateur. Il semble que, une fois une fois, Visual Studio n'a pas montré le constructeur par défaut d'IntelliSense, qui, à mon avis, est la chose sensible à faire. Mais les gens se sont plaints voir ici et à certains Point Il a dû être modifié, car maintenant Visual Studio 2010 apparaît le constructeur vide comme première option.