Question

Quelqu'un pourrait-il me conseiller sur la méthode à suivre lors de la rédaction d' C# les constructeurs?

Dans d'autres langues, comme l' C++, tout est fine - vous l'habitude de ne pas faire les champs internes visible et fournir des getters / setters pour eux.

Cela signifie, que vous puissiez offrir à votre classe avec des constructeurs, qui initialise tous les / certains de vos membres locaux et d'être heureux.


C#, cependant, a properties, qui nous permet d'écrire quelque chose comme:

Class x = new Class { Field1 = new Field1 ...., Field2 = new Field2 }

Cela permet le chaînage de la construction de l'objet et, comme je le suppose, peut supprimer un grand nombre de constructeurs, qui serait nécessaire si nous n'avions pas properties.

En combinant ceci avec des valeurs par défaut pour les propriétés, comme je le suppose, nous pouvons vous débarrasser complètement de non spécialisés, les constructeurs, qui, en fait, faire un peu de travail.

Maintenant, est-ce ok pour supprimer redondant constructeurs et permettre l'objet de la construction via la zone de l'initialisation?

Quels sont les inconvénients de cette approche?Quelqu'un pourrait-il donner recommandations générales sujet combinant l'utilisation de champs et des constructeurs, certains rules of thumb, sans doute?

Je vous remercie.

Était-ce utile?

La solution

Ma propre règle de base est simple: si quelque chose est nécessaire pour construire complètement l'objet, il devrait s'agir d'un paramètre CTOR.

Un bon exemple est l'un des objets d'assistance à flux tels que StreamReader ou BinaryReader.Ils ne peuvent pas fonctionner sans un objet de flux associé, afin que cela puisse être spécifié dans le constructeur.

Autres conseils

À mon avis, il n'y a rien de mal à avoir ce que vous avez des constructeurs redondants.Si cela donne un sens suffisant pour vous de vouloir définir un constructeur, c'est probablement parce qu'il y a un besoin authentique de le faire de cette façon.

Constructeurs peuvent être utilisés pour forcer le consommateur à fournir des valeurs à la classe.

Ma règle de base est que les champs sont destinés aux données facultatives, tandis que les constructeurs peuvent être utilisés pour forcer les données requises.

La question est quelque chose d'une fausse dichotomie cependant.C ++ se comporte de la même manière que c # - "champs" (qui sont en réalité les champs de propriétés sont des variables de niveau de classe) sont généralement utilisés comme getters / setters pour définir des valeurs internes et la syntaxe new qui vous permet de définir les champs est juste un raccourcipour

Class x = new Class();
x.Field1 = new Field1();
x.Field2 = new Field2();

la meilleure pratique consiste à créer un objet dans un état utilisable;Essayez de limiter la dépendance sur les constructeurs de propriétés.

Il réduit les chances que vous créez un objet incomplet et conduit à un code moins fragile.

Le code que vous avez affiché utilise ce qu'on appelle les initialisateurs d'objets, qui ne sont vraiment que du sucre syntaxique qui ont été introduits assez récemment.L'utilisation des initialisateurs d'objets ne sont qu'une façon abriante d'appeler des propriétés de constructeur et .Vous devriez continuer à utiliser des constructeurs en C # de la même manière que vous les avez utilisés dans d'autres langues - la règle générale est que si une classe nécessite un objet ou une valeur pour qu'elle soit initialisée correctement, ce paramètredevrait être passé à travers le constructeur.Si la valeur n'est pas nécessaire, il est raisonnable de le faire une propriété réglable.

D'une manière générale, j'évite d'utiliser des setters du tout lorsque cela est possible (il y en a beaucoup, beaucoup de cas quand ce n'est pas possible).

L'approche de la construction du paramètre public suivie de l'initialisation de la propriété est populaire (obligatoire?) Pour une utilisation dans XAML, de nombreux jouets WPF font cela.

Le seul problème que vous rencontrez est un objet partiellement initialisé, mais vous pouvez simplement valider l'état de l'objet avant de tenter d'utiliser les champs.

Personnellement, je fais des paramètres de valeurs critiques dans le constructeur, je fais des constructeurs de copies sur une copie de l'objet et une gamme de paramètres facultatifs, et je n'ai pas encore besoin de quelque chose qui a besoin de consommer par XAML.

La syntaxe d'initialisation d'objet est juste un sucre syntaxique.Même en C # 1, vous pourriez écrire

Class c = new Class();
c.Property1 = value1;
c.Property2 = value2;
c.Property3 = value3;
....

C # 3 raccourcit essentiellement la syntaxe à:

Class c = new Class 
{
   Property1 = value1, 
   Property2 = value2, 
   Property3 = value3
   ....
}

Le point OD Le Countrer n'est pas simplement de définir les champs, le constructeur doit construire logiquement l'objet, en fonction des paramètres, de sorte que lorsque le constructeur revienne, ce que vous obtenez est un objet qui est prêt à être utilisé.

Est-ce que ça va?Eh bien, cela dépend ...

Pour utiliser les initialiseurs d'objets, vous devrez exposer des setters publics dans tous vos champs, vous risquez de ne pas le vouloir.Si vous êtes heureux de les exposer, je dirais que je vais aller de l'avant et supprimer des constructeurs.Cependant, simplement parce que vous peut faire quelque chose ne signifie pas que vous devrait .Je dirais que la suppression des constructeurs devrait être quelque chose que vous effectuez si vous trouvez que tous vos champs sont réglables publiquement, ne rendez pas les champs réglables pour vous permettre de supprimer le constructeur.

Je suppose que vous vous référez à des objets de domaine ici, mais dans le cas des services, injecter les dépendances du service dans le cadre d'un constructeur rend le service plus automatiquement auto-documentant, par opposition à "nouveauté" de vos dépendances.En outre, cela vous permet d'utiliser plus facilement des conteneurs d'injection de dépendance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top