Faut-il toujours inclure un constructeur par défaut dans la classe?
J'ai été demandé à cette question par un collègue que devrions-nous toujours inclure un constructeur par défaut dans une classe? Si oui, pourquoi? Si non, pourquoi pas?
Exemple
public class Foo {
Foo() { }
Foo(int x, int y) {
...
}
}
Je suis également intéressé pour obtenir quelques lumières sur cette des experts.
- Comme d'habitude, seulement quand c'est nécessaire.
- Ouais, je suis aussi curieux. Mon manager me dit toujours que c'est nécessaire pour la Réflexion, mais je ne pouvais pas google quoi que ce soit, donc je suis un peu confus.
Vous devez vous connecter pour publier un commentaire.
Vous devez garder à l'esprit que si vous ne fournissez pas une surcharge du constructeur, le compilateur va générer un constructeur par défaut pour vous. Cela signifie que, si vous avez juste
Le compilateur va générer ce que:
Cependant, dès que vous ajoutez les autres constructeur
Le compilateur n'est plus automatiquement générer le constructeur par défaut pour vous. Si la classe était déjà utilisé dans un autre code qui s'appuyait sur la présence d'un constructeur par défaut,
Foo f = new Foo();
, que le code serait désormais rompre.Si vous ne voulez pas que quelqu'un soit capable d'initialiser la classe sans fournir de données, vous devez créer un constructeur par défaut qui est
private
d'être explicite sur le fait que vous êtes la prévention des instances de la construction avec pas de données d'entrée.Il ya des moments, cependant, quand il est nécessaire de fournir un constructeur par défaut (public ou privé). Comme il a été mentionné précédemment, certains types de sérialisation besoin d'un constructeur par défaut. Il y a aussi des moments où une classe possède plusieurs constructeurs paramétrés, mais nécessite aussi de "bas niveau" de l'initialisation, dans ce cas, un privé constructeur par défaut peut être utilisé, qui est enchaîné à partir de l'constructeurs paramétrés.
public
modificateurs là (les membres de la classe sontprivate
par défaut)...Foo f = new Foo();
. Cependant, dès que vous modifiez la classe pour que montré dans le troisième exemple,Foo f = new Foo();
provoquera une erreur de compilation, - ce qui était mon point. Tant que vous avez aucun constructeurs, le compilateur ajoute le constructeur par défaut pour vous. Dès que vous ajoutez des aucun autre constructeur, le compilateur n'ajoute plus le constructeur par défaut et le code qui s'appuyait sur elle présente des pauses.public Foo() : base() { }
et le messageThe generated constructor also calls the base default constructor, important to know when considering inheritance
(mdsn source). Si elle est approuvée ou pas, veuillez vérifier.Certaines choses (comme la sérialisation) besoin d'un constructeur par défaut. En dehors de cela, cependant, un constructeur par défaut ne doit être ajoutée si elle fait sens.
Par exemple, si le
Foo.X
etFoo.Y
propriétés sont immuables après la construction puis un constructeur par défaut n'a pas vraiment de sens. Même s'il était utilisé pour un 'vide' Foo, statiqueEmpty
accesseur serait plus détectable.ISerializable
, et d'ajouter un constructeur (private
si scellés,protected
autrement) avec la signatureClassName(SerializationInfo info, StreamingContext context)
qui reflète la mise en œuvre deISerializable.GetObjectData
.Je dirais pas, certainement pas toujours. Supposons que vous avez une classe avec certains champs en lecture seule qui doit être initialisée à une valeur, et il n'y a pas de défaut (ou vous ne voulez pas y être)? Dans ce scénario, je ne pense pas qu'un constructeur sans paramètre de sens.
Avoir un constructeur par défaut est seulement une bonne idée si il est logique d'avoir un tel objet.
Si vous produisez un objet qui n'est pas dans un état valide à partir d'un tel constructeur, alors la seule chose qu'il peut faire est de présenter un bug.
Comme une note de côté, lors de l'utilisation de struct au lieu de la classe, notez qu'il existe aucun moyen de quitter le constructeur par défaut, ni est-il possible de définir vous-même, donc, quels que soient les constructeurs vous définissez, assurez-vous que l'état par défaut de la structure (lorsque toutes les variables sont initialisées à leur état par défaut (généralement 0 pour les types de valeur, et la valeur null pour les types référence) ne cassera pas votre mise en œuvre de la struct.
Oui C'est mieux d'avoir un constructeur par défaut en place pour vous assurer d'éviter toute confusion. J'ai vu des gens tout simplement ne rien faire à l'intérieur d'un constructeur par défaut (même dans Microsoft classes) mais tout de même garder que les objets ne l'obtenez par défaut(type) automatiquement. Les classes qui ne spécifiez pas de constructeur par défaut, .NET ajoutera automatiquement pour vous.
Sérialisation besoins constructeur par Défaut si vous utilisez existant sérialiseurs que c'est logique pour usage général sérialiseurs, sinon vous avez besoin pour créer votre propre mise en œuvre.
ISerializable
, et d'ajouter un constructeur (private
si scellés,protected
autrement) avec la signatureClassName(SerializationInfo info, StreamingContext context)
qui reflète la mise en œuvre deISerializable.GetObjectData
.Dans la plupart des cas, un constructeur par défaut est une bonne idée. Mais puisque vous utilisez le mot "toujours", tout ce qui est nécessaire est un contre-exemple. Si vous regardez le Framework, vous trouverez beaucoup de choses. Par exemple, le Système de.Web.HttpContext.
Un type générique ne peut être instancié avec C# moyens (sans réflexion) si elle a un constructeur par défaut. Aussi, le
new()
générique type de contrainte doit être spécifié:L'appel de cette méthode à l'aide d'un type comme argument de type générique qui n'a pas de constructeur par défaut génère une erreur de compilation.