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

  1. #1
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    3 736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 3 736
    Points : 6 480
    Points
    6 480
    Billets dans le blog
    1
    Par défaut Généricité et accès à propriété statique
    Bonjour,

    J'ai une classe abstraite MyAdstract qui contient un certain nombre de propriétés et méthodes, y compris statiques.

    J'ai une classe générique MyGeneric<T> where T : MyAbstract

    Je souhaite dans des méthodes de MyGeneric appeler des propriétés ou méthodes statiques de T

    Par exemple :
    Code csharp : 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
    27
    28
    29
    30
    31
    32
    33
     
    abstract class MyAdstract
    {
        public static string Name = "undefined";
    }
     
    abstract class MyGeneric<T> where T : MyAdstract
    {
        List<T> MaListe;
     
        public MyGeneric()
        {
        }
     
        public string ListeDeQuoi()
        {
            return T.Nom + "s";
        }
    }
     
    public class Voiture : MyAbstract
    {
        public new static string Nom = "Voiture";
    }
     
    public class Train : MyAbstract
    {
        public new static string Nom = "Train ";
    }
     
    MyGeneric<Voiture> Voitures = new MyGeneric<Voiture>();
     
    Console.WriteLine(Voitures.ListeDeQuoi());

    Je voudrais récupérer "Voitures" en sortie.

    Sauf que dans ListeDeQuoi() monsieur le compilateur veut pas que j'utilise T... C'est un "paramètre de type" et non un "type" qu'il me dit
    On ne jouit bien que de ce qu’on partage.

  2. #2
    Expert éminent
    Homme Profil pro
    Responsable Datas
    Inscrit en
    janvier 2009
    Messages
    4 014
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Datas

    Informations forums :
    Inscription : janvier 2009
    Messages : 4 014
    Points : 9 345
    Points
    9 345
    Par défaut
    Bonjour,
    Pour moi tu ne peux pas accéder à T.Name"directement".
    Par contre comme la classe possède un membre de type List<T>, tu peux accéder à la propriété Name pour chaque élément de la liste, puisqu'ils sont de type T (qui ici est de type ou hérite du type MyAbstract).

    Et (je pense que) tu peux depuis la méthode ListeDeQuoi récupérer le type de T avec GetType().

    Tatayo.

  3. #3
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    avril 2007
    Messages
    13 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 13 655
    Points : 24 691
    Points
    24 691
    Par défaut
    pas évident de faire du polymorphisme avec du static ^^

    si tu veux un nom lisible en partant d'une classe je propose plutôt un attribut custom à mettre au dessus de la classe, ensuite en partant de typeof(T) tu peux demander l'attribut et la valeur d'une de ses propriétés

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [MyNameAttribute("Train")]
    public class Train : ...
    après si le nom de la classe te suffit c'est juste TypeOf(T).Name
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    3 736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 3 736
    Points : 6 480
    Points
    6 480
    Billets dans le blog
    1
    Par défaut
    Merci tatayo pour ta réponse rapide et précise

    Mon souci, c'est que mon List<T> n'est pas forcément rempli...

    On va dire par exemple que je souhaite justement implémenter une class "Add" qui va effectuer un traitement différent en fonction du T.Nom (sachant que deux classes peuvent avoir le même "Nom").

    J'ai trouvé une parade qui est loin de me convaincre...
    Finalement, j'ai passé mes membres et méthode en non static... et je fais :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        public string ListeDeQuoi()
        {
            T tmp = default;
            return tmp.Nom + "s";
        }

    Le souci c'est que je suis du coup obligé d'instancier un objet pour rien...
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    3 736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 3 736
    Points : 6 480
    Points
    6 480
    Billets dans le blog
    1
    Par défaut
    Alors là, je suis complètement perplexe...

    Le truc compile mais ne fonctionne pas.
    Et là j'ai tout cassé et ça fait n'importe quoi...

    Verrai demain à tête reposée
    On ne jouit bien que de ce qu’on partage.

  6. #6
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    avril 2007
    Messages
    13 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 13 655
    Points : 24 691
    Points
    24 691
    Par défaut
    Default ça veut dire la valeur par défaut pour le type, soit null pour un objet (0 pour un int...)
    Si tu veux instancier faut faire new T
    Et pour avoir le droit d'écrire new T il faut le préciser au compilateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       public class C1<T> where T : new()
            {
     
            }
    Mais en effet être obligé d'instancier c'est pas top, d'où ma première réponse...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

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

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : février 2010
    Messages : 3 552
    Points : 9 880
    Points
    9 880
    Billets dans le blog
    3
    Par défaut
    Que cherches-tu a faire :
    1 - Tu veux afficher le nom du type de T ?
    2 - Tu veux appeler le member Name du type MyAbstract ?

    Pour 1, voir la methode ListeDeQuoi() ; pour 2, voir la methode ListeDeQuoi2() :

    Code C# : 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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    public abstract class MyAbstract
    {
    	public static string Name = "undefined";
    }
     
    public class MyGeneric<T> where T : MyAbstract
    {
    	List<T> MaListe;
     
    	public MyGeneric()
    	{
    	}
     
    	public string ListeDeQuoi()
    	{
    		return typeof(T).Name + " (typeof(T))";
    	}
     
    	public string ListeDeQuoi2()
    	{
    		var t = typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Static).First();
     
    		return ((FieldInfo)t).GetValue(this)?.ToString();
    	}
    }
     
    public class ClassVoiture : MyAbstract
    {
    	public new static string Name = "Voiture (MyAbstract.Name)";
    }
     
    public class ClassTrain : MyAbstract
    {
    	public new static string Name = "Train (MyAbstract.Name)";
    }
     
    class Program
    {
    	static void Main(string[] args)
    	{
     
    		MyGeneric<ClassVoiture> Voitures = new MyGeneric<ClassVoiture>();
     
    		Console.WriteLine("Methode 1: " + Voitures.ListeDeQuoi());
    		Console.WriteLine("Methode 2: " + Voitures.ListeDeQuoi2());
    		Console.ReadLine();
    	}
    }
    Resultat :
    Methode 1: ClassVoiture (typeof(T))
    Methode 2: Voiture (MyAbstract.Name)
    Pour la methode 2, il est deconseille d'avoir des membres publics, il vaut mieux avoir une propriete publique. Mais bon parfois il n'y a pas le choix…
    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.

  8. #8
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    3 736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 3 736
    Points : 6 480
    Points
    6 480
    Billets dans le blog
    1
    Par défaut
    J'ai fini par trouver mon bonheur...

    Ça fait usine à gaz un peu quand même !

    Code csharp : 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
     
            public T GetById(int id)
            {
                T res = DonneesEnCache.FirstOrDefault(a => a.ID == id);
                if (res == null)
                {
                    Type objType = typeof(T);
                    string tablename = (string)objType.GetField("TABLENAME").GetValue(null);
                    string[] fields = (string[])objType.GetField("FIELDS").GetValue(null);
                    object[] values = DataLoader.SelectOne(tablename, fields, id);
                    if (values == null)
                    {
                        return null;
                    }
                    else
                    {
                        res = (T)objType.GetMethod("DatabaseLoad").Invoke(null, new object[] { values });
                        if (res != null)
                        {
                            DonneesEnCache.Add(res);
                        }
                    }
                }
                return res;
            }
    On ne jouit bien que de ce qu’on partage.

  9. #9
    Expert éminent sénior

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

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

    Informations forums :
    Inscription : juillet 2016
    Messages : 2 579
    Points : 10 165
    Points
    10 165
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Sauf que dans ListeDeQuoi() monsieur le compilateur veut pas que j'utilise T... C'est un "paramètre de type" et non un "type" qu'il me dit
    C'est normal. Les membres statiques ne font pas parti de la classe à proprement parler (la classe n'est qu'un espace de nommage). Tes classes qui héritent de MyAbstract n'ont pas de propriété Name "par héritage", et si tu faisais un Voiture.Nom sans redéfinir la propriété nom tu devrais avoir une erreur de compilation.

    Du coup, quand tu as un paramètre générique T, même si tu précises que T doit dériver de MyABstract, cela ne donne aucune information sur les membres statiques.

    La seule solution consiste donc à utiliser la réflexion, comme tu as su le faire (ou transformer les membres statiques en membres d'instances, mais du coup, il faut... une instance)
    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

  10. #10
    Membre expérimenté
    Homme Profil pro
    edi
    Inscrit en
    juin 2007
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : juin 2007
    Messages : 738
    Points : 1 564
    Points
    1 564
    Par défaut
    J'ai l'impression que ce que tu cherches à obtenir ce sont des métadonnées associées à une classe. Dans ce cas l'idiome typique pour le faire est comme l'a proposé Pol63 de passer par des attributs custom. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    public class EntityMetadataAttribute : Attribute
    {
        public EntityMetadataAttribute(string name)
        {
            Name = name;
        }
     
        public string Name { get; }
        public string PluralName { get; set; }
     
        public static EntityMetadataAttribute ForType<T>() => ForType(typeof(T));
        public static EntityMetadataAttribute ForType(Type type) => type.GetCustomAttribute<EntityMetadataAttribute>();
    }
    Une classe est annotée de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [EntityMetadata("Voiture", PluralName = "Voitures")]
    public class Voiture
    {
     
    }
    Et le code utilisateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public static T Create<T>() where T : new()
    {
        Console.WriteLine("new " + EntityMetadataAttribute.ForType<T>().Name);
        return new T();
    }

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

Discussions similaires

  1. [Objet] Accès à propriété privée depuis méthode statique
    Par Blaise1 dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 20/09/2011, 14h39
  2. probleme accès methode statique
    Par jpsegret dans le forum Langage
    Réponses: 5
    Dernier message: 02/04/2007, 16h40
  3. Accès propriété repertoire virtuel
    Par helios77 dans le forum IIS
    Réponses: 1
    Dernier message: 21/03/2007, 21h42
  4. accès à propriété css
    Par WalidNat dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 31/10/2006, 20h47
  5. [AS2] Pb accès fonctions statiques
    Par wwave dans le forum ActionScript 1 & ActionScript 2
    Réponses: 1
    Dernier message: 08/02/2006, 15h18

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