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 :

Génériques => Type de la classe conteneur en paramètre


Sujet :

C#

  1. #1
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut Génériques => Type de la classe conteneur en paramètre
    (re) bonjour @ tous,

    Voilà, c'est un peu tordu comme question, mais est ce qu'on peut éviter de répéter le nom de la propre classe dans les méthodes enfants, et plutôt utiliser un terme générique ?
    Pas exemple, je fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public class tblGridGroups : IDataAccessServiceGroups {
            public static tblGridGroups OrEmptyIfNull(tblGridGroups source) {
                return source ?? new tblGridGroups();
            }
    }
    Est ce que ce ne serait pas possible de faire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public class tblGridGroups : IDataAccessServiceGroups {
            public static typeof(this) OrEmptyIfNull(typeof(this) source) {
                return source ?? new typeof(this)();
            }
    }
    Dans l'idée bien sur, ca je sais que ceci ne compile pas.
    David.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Points : 1 498
    Points
    1 498
    Par défaut
    Salut,

    C'est tout a fait possible via generiques et encore mieux via methodes d'extentions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    public class tblGridGroups : IDataAccessServiceGroups
    {
    }
     
    public static class Extentions
    {
    	public static T OrEmptyIfNull<T>(this T source)
    		where T: IDataAccessServiceGroups, new()
    	{
    		return source ?? new T();
    	}
    }
     
    //utilisation
    IDataAccessServiceGroups plop;
    var plop2 = plop.OrEmptyIfNull();

  3. #3
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Bonjour mermich,

    Oui, j'utilise les méthodes d'extension, et c'est vrai que c'est pas mal.
    Alors, oui. Pour cet exemple ça peut coller car il n'y a pas de propriétés propriétaires à la classe dans la méthode, mais si je prend par exemple une fonction comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
            /// <summary>Ajoute un élément à la BDD.</summary>
            /// <param name="u">Element à ajouter.</param>
            /// <returns>OK=Element ajouté, KO=null (le message d'erreur est dans vmBase).</returns>
            public static tblGroup Add(tblGroup u) {
                if ((u != null)) {
                    return Sauver(u.id, u.name, u.value); // Exemple grossier, pour simplifier.
                } else
                    return null;
            }
    Ça ne fonctionne plus, et même si on y arrive, il n'y a plus d’intérêt de mettre ça en méthode d'extension car chaque classe est gérée différemment, en fonction de ses propriétés.

    Tu parlais des génériques... peux tu détailler STP ?
    David.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Points : 1 498
    Points
    1 498
    Par défaut
    Je ne comprends pas, tu veux factoriser du code propre a chaque classes, et ensuite tu dis que ce n'est pas possible .

    Oui evidemenent, mais d'un autre cote je ne comprends pas ce que tu veux vraiment faire et ou tu veux en venir.

  5. #5
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Non, je ne veux pas factoriser, Je veux juste remplacer le nom de la l'objet de la classe dans laquelle il se trouve par un terme générique (à la nameof, ...).

    En clair, de ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class tblGridGroups {
            public static tblGroup Add(tblGroup u) {
                if ((u != null)) {
                    return Sauver(u.id, u.name, u.value); // Exemple grossier, pour simplifier.
                } else
                    return null;
            }
    }
    Faire ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class tblGridGroups {
            public static typeof(this) Add(typeof(this) u) {
                if ((u != null)) {
                    return Sauver(u.id, u.name, u.value); // Exemple grossier, pour simplifier.
                } else
                    return null;
            }
    }
    Le typeof(this) n'existe pas, bien sur, mais c'est l'idée.
    Récupérer le type du conteneur via un accesseur et qui permette d'être utilisé comme type déclaratif.
    ... Je ne suis pas sur que ce soit plus clair expliqué comme ça... 0_0

    Dans mes classes objets, je répète une bonne 30aine de fois le nom de la classe, et je voulais optimiser ça (pour faciliter les copier/coller ou renommages par exemple).
    Juste savoir si un truc existait.
    David.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,
    Si toutes tes classes implémentent la même interface, tu peux utiliser cette interface comme type de retour.

  7. #7
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Bonjour Ebastien,

    Je ne suis pas sur de bien comprendre.
    Mais en tout cas, non, elles n'implémentent pas toutes la même interface, et ce que je veux faire est remplacer les X nom de ma classe par un terme générique, non pas par un autre nom de classe local.
    Mais a première vue, ca n'a pas l'air d'exister...
    David.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Points : 1 745
    Points
    1 745
    Par défaut
    Si je comprends bien, tu as une trentaine de classes qui implémentent toutes une méthode statique de même nom et de même signature (au nom de la classe près)
    Donc soit tu utilises un générique mais dans ce cas, tu ne pourras pas utiliser des propriétés propres à ta classe dans les signatures des méthodes utilisées par ta méthode statique.
    Soit tu utilises une interface commune à toutes tes classes (rien ne t'empêche de la créer sachant qu'une classe peut implémenter plusieurs interfaces).
    Soit tu peux aussi faire hériter toutes tes classes d'une classes de base et utiliser cette classe de base (ce qui revient à peut près au même que l'interface)
    Soit j'ai pas compris ton problème.

  9. #9
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Je ne sais même pas si c'est possible de faire ce que tu dis... 0_0

    C'est beaucoup plus simple que ça... Mais j'ai du ma à m'expliquer, on dirait.

    J'ai plusieurs classes dans mon projet, forcément. Mais ici, on parle d'une seule.... Qui a bien un nom unique (disons C, pour l'exemple).
    Toute ma question se passe uniquement à l'intérieur de cette classe, sur les méthodes de cette classe (une trentaine).
    J'ai des méthodes (dans C) qui prennent en paramètre C ou/et qui renvoient C.

    Plutôt que d'écrire le type C (public C MaMethode(C monParam) { ... }), je voulais savoir s'il n'y avait pas un terme générique.. De la réflexion en gros, qui existait, genre : de type "papa".
    David.

  10. #10
    Membre expérimenté
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Points : 1 745
    Points
    1 745
    Par défaut
    Ah ok, effectivement, je n'avais pas compris ça.
    Alors ce que je ne comprends pas c'est que même s'il existait un terme générique, ça reviendrait au même de répéter ce terme partout ou d'écrire le nom de ta classe partout. Et si tu veux modifier un jour le nom de ta classe, le refactoring de VS fonctionne très bien.

  11. #11
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Points : 1 498
    Points
    1 498
    Par défaut
    Dans ce cas, il y a un moyen, mais honettement, je vois pas l'interet:

    Le truc est d'encapsuler la classe dans ta 'meme' classe en 'generique':

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public class plop
    {
        public int id { get; set; }
        public int name { get; set; }
        public int value { get; set; }
    }
     
    public class plop<T> where T : plop
    {
        private static T instance;
     
        public static T Add(T u)
        {
        if ((u != null)) {
            return Sauver(u.id, u.name, u.value); // Exemple grossier, pour simplifier.
        } else
            return null;
     
    }
     
        static T Sauver(int id, int name, int value)
        {
            //
            return instance;
        }
    }
    du coup tu wrap ta classe plop dans un conteneur de plop et t'as pas besoin de repeter le type, mais je vois pas l'interet.

  12. #12
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    En effet, c'est un peu prendre un marteau pilon pour écraser une mouche.
    Mon besoin est que je suis souvent amené à faire du copier/coller de classe.
    J'ai beaucoup de tables et plutôt que de réécrire ma classe modèle, je démarre d'une classe similaire que j'adapte ensuite (Je sais, ce n'est pas chouette, mais chuuut. ;-) )

    Et en effet, le refactoring fonctionne bien, je l'utilise beaucoup, mais un peu trop bien même, car si on a 2 classes de même noms, il renomme les 2 des fois.

    Bref, un truc simple à la nameof() n'existe pas, je laisse tomber l'affaire.
    J'aurais au moins réussi à me faire comprendre... Et ce, un vendredi à 17H, hi.

    Merci pour votre participation et très bon WE à vous.
    David.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 24/06/2009, 12h30
  2. définition de type dans une classe générique
    Par Benoit_T dans le forum Delphi .NET
    Réponses: 2
    Dernier message: 16/03/2009, 17h24
  3. héritage et pointeur générique de type classe mere
    Par contremaitre dans le forum C++
    Réponses: 12
    Dernier message: 07/01/2009, 13h51
  4. Réponses: 4
    Dernier message: 30/01/2008, 14h45
  5. Conteneur générique et types des objets contenus
    Par bobuse dans le forum Langage
    Réponses: 4
    Dernier message: 12/04/2007, 11h59

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