IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Annuler une construction [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut Annuler une construction
    Bonjour,

    J'ai un constructeur qui prend un argument.

    Si la valeur de cet argument n'est pas valide, que puis-je faire ?
    Jeter une exception ? Pas d'autres solution ?

  2. #2
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Bonjour,

    Jeter une exception dans un constructeur est une très mauvaise pratique. En C#, ça va parce que tout est géré par le framework mais dans certains langages comme c++ ça peut être très problématique car tu peux te retrouver avec des objets incomplets.

    Le meilleur à faire dans ton cas serait de créer une Factory qui vérifie ton argument et renvoie ton objet. Je te laisse googler ce design pattern afin d'en savoir plus mais il n'y a rien d'extrèmement compliqué
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  3. #3
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Je voudrais faire entendre un son de cloche différent. Lancer des exceptions depuis un constructeur ne pose aucun problème et, d'ailleurs, plusieurs types du framework font cela. Il ne faut donc surtout pas hésiter à mes yeux, surtout s'il ne s'agit que de quelques vérifications.

    Cela dit, attention tout de même ! Si une exception est lancée dans le constructeur, il est vrai que l'objet ne sera pas accessible par le code qui instanciait, ce qui est bien (même en cas de bloc using sur un type implémentant IDisposable : on n'entrera jamais dans le bloc et Dispose ne sera jamais appelé). En revanche, l'instance a bien été créée et reste accessible par le seul GC qui appellera le destructeur. C'est la grosse différence avec le C++. Gaffe, donc, a bien écrire la destructeur avec cette perspective en tête.

    Enfin, utiliser une méthode factory statique (MyType.Create()) me semble toutefois acceptable dans le cas d'un processus de création particulièrement coûteux (temps CPU, ressources systèmes, etc). Non pas que cela poserait problème si c'était fait dans un constructeur mais on attend intuitivement d'un constructeur qu'il soit léger. Garder le constructeur privé et fournir une telle méthode statique est donc une simple indication à l'usage des consommateurs de la classe. Mais c'est lourd et en abuser est à mes yeux un anti-pattern. Je garde plutôt ces méthodes pour les cas où je préfère renvoyer null plutôt que de lever une exception où, bien sûr, pour tous les cas où le pattern factory est approprié.


    PS : MSDN est toujours une bonne source : Constructor design guidelines

  4. #4
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Par défaut
    salut

    vu que ton constructeur prends un argument, rien n'empeche ton objet après construction de positionner un "état - Je suis pas bien construit"...

    Après, en théorie, si la construction de ton objet est impossible parce que un argument contient une mauvaise valeur, alors il vaut peut-etre mieux une factory...

    Ou alors, construire ton objet et avoir une méthode dans laquelle tu passes ton argument et qui te retournera un boolean pour dire si les choses à construire à partir de cet argument se sont construites

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 202
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message
    Jeter une exception dans un constructeur est une très mauvaise pratique. En C#, ça va parce que tout est géré par le framework mais dans certains langages comme c++ ça peut être très problématique car tu peux te retrouver avec des objets incomplets.
    ne pas répondre sur un langage avec des arguments d'un autre langage ...

    et pour compléter DonQuiche que je puissoie, en général le throw est fait au début du constructeur, (if arg is null {throw argumentnullexception} par exemple) donc ça ne pose pas de soucis niveau mémoire
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Par défaut
    salut

    moi, comme je suis un peu neuneu, ce que je fais est un peu ce que fait Microsoft...

    Prenons l'exemple de la classe SerialPort qui permet de faire de la communication série. Si on regarde cette classe, dans le constructeur, on peut passer des arguments... Par contre, ce sont les méthodes de "communication" qui elles vont retourner une exception ou un boolean pour dire "Pas de Port Série".

    Et pour moi, c'est plutot logique...

    Pour moi, une classe devrait toujours pouvoir être construite. Par contre, si défaut d'argument, de ressources disponibles il y a , alors, les méthodes "obligatoires" de cette classe te le diront dès le premier appel.

    J'ai JAMAIS au cours de ma courte carrière de développeur (27 ans de dév ) eu une situation ou je me suis dit "Tiens, je vais lancer une exception dans mon constructeur"...

    Peut-etre parce que je privilégie les choses simples aux choses compliquées, alambiquées, divines au niveau design mais impossible à réaliser dans le temps imparti.. Peut-etre parce que je pense qu'un logiciel doit avant tout apporter la réponse au besoin avant d'être "magnifique" d'un point de vue architecture...

    En tout cas, même si la question est pertinente et interessante, j'avoue ne jamais avoir eu à traiter ce type de cas...

    Peut-etre que je crois trop que l'informatique, c'est TOUJOURS simple...

    Ma devise : "En informatique, rien n'est compliqué. Par contre, parfois, résoudre un problème peut-etre complexe"...

  7. #7
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 202
    Par défaut
    Citation Envoyé par theMonz31 Voir le message
    Prenons l'exemple de la classe SerialPort qui permet de faire de la communication série. Si on regarde cette classe, dans le constructeur, on peut passer des arguments... Par contre, ce sont les méthodes de "communication" qui elles vont retourner une exception ou un boolean pour dire "Pas de Port Série".

    Et pour moi, c'est plutot logique...

    Pour moi, une classe devrait toujours pouvoir être construite. Par contre, si défaut d'argument, de ressources disponibles il y a , alors, les méthodes "obligatoires" de cette classe te le diront dès le premier appel

    je ne suis pas trop d'accord
    en général dans une application on log les erreurs pour pouvoir débugger rapidement

    si une classe demande un paramètre dans son constructeur et qu'elle en a réellement besoin, ca me parait plus logique de thrower tout de suite, au moins dans le stacktrace on saurait à quel moment le paramètre était null
    car les objets peuvent venir de loin ... et si tu throw lors d'un appel à une méthode, tu ne sauras pas forcément à quel moment tu as instancié ta classe et donc le debug en sera moins aisé
    CA ça me parait logique !

    après si le paramètre n'est pas nécessaire au moment de la construction et peut etre fourni plus tard pas de soucis
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Membre expérimenté Avatar de brachior
    Homme Profil pro
    Doctorant
    Inscrit en
    Mai 2011
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2011
    Messages : 190
    Par défaut
    Citation Envoyé par Pol63
    si une classe demande un paramètre dans son constructeur et qu'elle en a réellement besoin, ca me parait plus logique de thrower tout de suite
    Je suis aussi de cet avis,
    Si un constructeur ou une méthode ne peut résoudre un problème,
    Il est de son devoir d'en avertir au plus vite l'objet appelant ...

    L'objet sera forcement créé mais seul le Garbage aura un pointeur dessus
    (Ce qu'on appelle un «constructeur» est en fait un «initialisateur» ... La construction a déjà été faite avant ...
    Dans certains langages, il est possible de faire son propre constructeur (ex: python))

    Si le fait d'avoir un objet inutilisable qui traine au niveau du Garbage te gène,
    (parce qu'il est trop lourd, et/ou parce qu'il y en aura peut être beaucoup)
    Alors une Factory te sortirait de là ^^.

  9. #9
    Membre Expert Avatar de Er3van
    Homme Profil pro
    Architecte Logiciel
    Inscrit en
    Avril 2008
    Messages
    1 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte Logiciel
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2008
    Messages : 1 430
    Par défaut
    Citation Envoyé par theMonz31 Voir le message
    Peut-etre que je crois trop que l'informatique, c'est TOUJOURS simple...
    L'informatique généralement c'est simple, à échelle micro, par contre, à échelle macro, ça ne l'est pas toujours.
    Et quand tu développes une solution IT qui répond à un besoin métier complexe, ta solution IT peut devenir complexe par extension (ou propagation...).

    Du coup, oui, quand tu fais une solution IT pour un besoin IT, ça me parait totalement justifié d'avoir recours à ce genre de pratique :
    Citation Envoyé par theMonz31 Voir le message
    Si on regarde cette classe, dans le constructeur, on peut passer des arguments... Par contre, ce sont les méthodes de "communication" qui elles vont retourner une exception ou un boolean pour dire "Pas de Port Série".
    Car dans ce cas, quelqu'un avec la compréhension métier de ton application qui doit un jour comprendre les mécanismes utilisés comprendra la raison.

    Par contre, dans le case d'une solution IT pour un besoin business, ça me parait totalement justifié d'avoir recours à ce genre de pratique là :
    Citation Envoyé par Pol63
    si une classe demande un paramètre dans son constructeur et qu'elle en a réellement besoin, ca me parait plus logique de thrower tout de suite, au moins dans le stacktrace on saurait à quel moment le paramètre était null
    Qui se traduirait par exemple par un :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    try {
           CreateCommand(product, customer);
    }
    catch(CommandCreationException cce) { /* do something */ }
    Car dans ce cas, tu sais que telle création n'a pas fonctionné, c'est aussi simple que ça. Tu décomposes ainsi de façon plus "macro".

    Du coup, j'aurais tendance à dire que vous avez tous raison, mais que c'est le contexte d'application qui fait la différence.

  10. #10
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 202
    Par défaut
    Citation Envoyé par Er3van Voir le message
    Du coup, j'aurais tendance à dire que vous avez tous raison, mais que c'est le contexte d'application qui fait la différence.
    c'est ce que j'aurais tendance à dire aussi
    selon la classe le développeur doit choisir entre un factory, un throw dans le constructeur, ou un throw plus tard comme pour le serialport
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. annuler une impression en cour
    Par mondanikoffi dans le forum Bases de données
    Réponses: 1
    Dernier message: 05/07/2005, 20h56
  2. [Info]comment annuler une Externalization string?
    Par car dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 17/04/2005, 09h51
  3. [JInternalFrame] Annuler sa construction
    Par wonderyan dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 12/03/2005, 16h58
  4. Annuler une insertion dans un Trigger
    Par dreamanoir dans le forum Oracle
    Réponses: 2
    Dernier message: 10/01/2005, 13h04
  5. Annuler une suppression
    Par Harbaingan dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 09/04/2003, 14h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo