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 :

Classe générique, constructeur et initialisation.


Sujet :

C#

  1. #1
    Membre éprouvé
    Homme Profil pro
    Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique
    Inscrit en
    Décembre 2014
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique

    Informations forums :
    Inscription : Décembre 2014
    Messages : 448
    Points : 990
    Points
    990
    Par défaut Classe générique, constructeur et initialisation.
    Bonjour, je ne sais pas trop par quel bout prendre ma question.

    Elle concerne les classes et méthodes génériques... mettons que je veuille passer un peu n'importe quoi donc une string ou une liste/dictionary de string, peu importe. Le problème se pose surtout pour les dictionary / liste je vais donner un bout de code basique pour me faire comprendre. Mettons une petite classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Machin<T>:
    {
    public T Test{get; set;}
     
    public Machin()
    {
    // Comment initialiser Test ?
    }
     
    }
    Machin selon les circonstances j'ai envie que ça soit un dictionary<string, string>, une List<string> peu importe....

    Je sais que si dans une autre fonction après avoir créé mon nouvel objet Machin:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //...
    Machin<Dictionary<string, string>> chouette = new Machin<Dictionary<string, string>>();
    chouette.Test.Add(a,b);
    je vais me manger un bug dans les gencives, qui sera d'ailleurs pas clair selon avec quoi j'ai couplé lié au fait que mon dictionary n'aura pas été initialisé. Mais dans le constructeur de Machin je ne peux pas initialiser par un Test = new T();

    La seule façon que j'ai vu qu'il était possible de faire c'est après la création de l'objet, dans mon autre portion de code, de faire donc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    //...
    Machin<Dictionary<string, string>> chouette = new Machin<Dictionary<string,string>>();
    chouette.Test = new Dictionary<string,string>;
    chouette.Test.Add(a,b);
    or je me dis qu'il doit certainement y avoir une façon d'initialiser Test avec le constructeur, pour ne pas avoir à chaque fois à réécrire une ligne après avoir créé un nouvel objet Machin, mais je sèche.

    Désolé mais j'ai repris mon code hier, après un mois d'arrêt, un passage sur python pour faire un "petit" programme, ce qui fait que je suis pas mal embrumé.
    Dans mon cas cette fonction est plus complexe que là, dans mon code, j'ai juste imaginez un bout de code pour l'essence. A la base ça sert couplé avec un decoupage du code pour lire dans la base de donnée, et je me suis mangé toute la journée un bug que je viens à peine de comprendre car au niveau des exceptions c'était très loin d'amener à une erreur facilement interprétable, mais bref le soucis venait de cette initialisation.

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Il te manque juste la contrainte de type new() sur ta classe :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    class Machin<T> where T : new()
    Cette contrainte permet de s'assurer que le type T dispose bien d'un constructeur public. S'il n'en a pas, tu ne pourras pas l'utiliser ce type en tant qu'argument.

    Ensuite tu peux initialiser ta propriete dans le constructeur :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Machin()
    {
        this.Test = new T();
    }
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  3. #3
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Autre méthode : utiliser la réflexion pour instancier le type T.

    Cette méthode n'est pas à utiliser en priorité. il faut utiliser la spécification de la contrainte new autant que possible, car le compilateur peut faire les vérifications nécessaires lors de la compilation. Malheureusement, cette spécification souffre d'une limitation parfois handicapante : le constructeur doit être sans paramètre.

    Dans le cas où on a besoin d'un paramètre, il faut alors se tourner vers la réflexion. Mais si erreur il y a, elle ne sera détectée qu'à l'exécution...
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  4. #4
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par François DORIN Voir le message
    Dans le cas où on a besoin d'un paramètre, il faut alors se tourner vers la réflexion. Mais si erreur il y a, elle ne sera détectée qu'à l'exécution...
    Merci pour la precision

    A noter qu'il existe d'ailleurs d'autres methodes pour eviter la reflexion dans le cas ou on a des parametres dans le constructeur, comme utiliser un delegue, ou encore utiliser le pattern factory et lister les constructeurs disponibles. Elles sont exposees ici : Is there a generic constructor with parameter constraint in C#?
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique
    Inscrit en
    Décembre 2014
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique

    Informations forums :
    Inscription : Décembre 2014
    Messages : 448
    Points : 990
    Points
    990
    Par défaut
    Merci beaucoup, en fait j'ai utilisé soit new() en contrainte de type, soit l'initialisation dans le constructeur mais je n'ai pas songé à utiliser les deux ensemble . Je vais tester ça de suite.

    Pour ce qui est de la réflexion, faut que je me replonge dans le bain mais merci pour cette information car je n'y aurais pas songé seul.


    correction avec les nouveaux éléments (si d'autres se posent la question):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    class Machin<T>:  /*classe dont on hérite si besoin*/ where T:new()
    {
     
    public T Test{get; set;}
     
    public Machin()
    {
    Test = new T();
    }
     
    }

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

Discussions similaires

  1. Classes génériques et constructeur
    Par othebault dans le forum Langage
    Réponses: 1
    Dernier message: 10/09/2009, 12h00
  2. Constructeur d'une classe générique
    Par Bobbledople dans le forum C#
    Réponses: 2
    Dernier message: 16/06/2009, 12h00
  3. Réponses: 5
    Dernier message: 13/05/2009, 18h22
  4. Réponses: 2
    Dernier message: 12/10/2008, 19h19
  5. [Generics] Classe générique
    Par norkius dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 15h57

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