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 :

Probleme de surcharge


Sujet :

C#

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 153
    Points : 161
    Points
    161
    Par défaut Probleme de surcharge
    Hello,

    C'est plus par curiosité qu'autre chose mais je suis tombé sur un comportement que je ne comprend pas vraiment entre surcharge et héritage.
    Voici un premier bout de code sur la surcharge:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class MaClasse
    {
        public void Test(int i)
        {
     
        }
        public void Test(object i)
        {
             Test((int)i);
        }
    }
    Si je fais ce code de test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MaClasse elt = new MaClasse();
    object o = 2;
    elt.Test(o);
    Le code va passer dans la fonction "Test(object)", caster mon paramètre en int, et appeler la fonction "Test(int)"... parce que mon type "int" est plus haut dans la hiérarchie d'héritage que object. Donc la, je suis content. Maintenant un autre code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class NewList<T> : List<T>
    {
          public void Add(object o)
          {
              Add((T)o);
          }
    }
    Ici, on est plus ou moins dans la même situation. La classe List<T> a une methode "Add(T)", et donc j'avais espéré que mon code de Add(object) allait utiliser le Add(T) en second appel.... et bien non. Il va juste s'appeler en boucle et partir en StackOverflow.

    Pour être tout a fait franc, il n'y a même pas besoin de lancer le code... Faire "F12" sur la ligne Add((T)o); vous emmènera a la ligne public void Add(object o).

    Quelqu'un pourrait-il m'expliquer la différence?

  2. #2
    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
    Points : 5 194
    Points
    5 194
    Par défaut
    c logique:

    tu appelles Add() dans la méthode Add() donc ça part en boucle.

    C'est quoi le rapport entre l'exemple 1 et le second ? ya autant de rapport qu'entre le chocolat et la choucroute !

  3. #3
    Membre habitué
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 153
    Points : 161
    Points
    161
    Par défaut
    Ben le rapport c'est que dans ma tete je vois pas de difference entre
    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
     
            public abstract class Foo
            {
                public void Test(int i)
                {
     
                }
            }
            public class Bar : Foo
            {
                public void Test(object i)
                {
                    Test((int)i);
                }
            }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            public class Bar 
            {
                public void Test(int i)
                {
     
                }
                public void Test(object i)
                {
                    Test((int)i);
                }
            }
    Et que clairement ces codes ont un comportement complément différent, et donc apparemment une fonction hérité est moins visible qu'une fonction directement code dans une classe...

  4. #4
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    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 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    La différence est tout à fait normal. C'est le jeu de l'héritage. Les deux exemples ne sont pas équivalents.

    Dans le premier cas, la classe définie 2 surcharges d'une même méthode. A la compilation, le compilateur peut choisir la surcharge appropriée (et dans les cas où il ne le peut pas, il génère une erreur "appel ambigu").

    Dans le second cas, la classe définie dispose :
    • D'une méthode Add(object) ;
    • D'une méthode héritée Add(T).


    Ainsi, la classe NewList ne dispose que d'une seule surcharge de la méthode Add, et hérite d'une autre méthode Add.

    Lorsque le compilateur se retrouve fasse à un objet de type NewList, et qu'il doit appeler la méthode Add, il regarde la surcharge définie au niveau de la classe et choisi celle qui convient. Uniquement dans le cas où cela ne serait pas le cas, le compilateur recherche dans la hiérarchie si une méthode peut convenir.

    Dans ton cas, pour lever l'ambiguïté (qui n'en est pas une pour le compilateur), tu dois utiliser la syntaxe base.Add lorsque tu appelles la méthode Add au sein de ta méthode Add. Ainsi, tu précises que dans la méthode Add de ta classe NewList, tu appelles la méthode Add définie par héritage.

  5. #5
    Membre habitué
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 153
    Points : 161
    Points
    161
    Par défaut
    Ahh ca c'est une explication qui me plait bien. Et finalement ca parait être une bonne décision de la part du compilateur de pas visiter systématiquement toutes les dépendances, parce que ca pourrait rapidement vite causer des ambiguïtés sur des fonctions ultra-standard telle que Equals.

    Par contre, ca met en évidence un "bug" dans Visual Studio, qui ne devrait pas me proposer cette syntaxe:
    Nom : syntaxe_error.png
Affichages : 169
Taille : 3,7 Ko
    Il devrait au moins y avoir un warning ou quelque chose.

    Merci

  6. #6
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    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 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par talrashha Voir le message
    Il devrait au moins y avoir un warning ou quelque chose.
    C'est pas vraiment un bug. On est dans le cas d'une surcharge très particulière où la seule différence réside dans le type du paramètre, qui dans un cas est spécialisé et dans l'autre générique, et pour lequel la méthode générique peut être appelée à tous les coups.

    Maintenant, dans la plupart des cas, la surcharge met en oeuvre un nombre de paramètres variables et/ou des types d'objet totalement différents, non reliés entre eux par une relation d'héritage. Et là, on est bien content que Visual Studio nous propose toutes les possibilités

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

Discussions similaires

  1. Obtention de i trema probleme de surcharge
    Par samouille666 dans le forum Débuter
    Réponses: 15
    Dernier message: 26/10/2009, 04h30
  2. probleme de surcharge...
    Par le_voisin dans le forum Boost
    Réponses: 5
    Dernier message: 03/03/2009, 17h51
  3. [POO] Probleme de surcharge d'operateur
    Par wawa84 dans le forum C++
    Réponses: 2
    Dernier message: 19/10/2008, 20h52
  4. Probleme de surcharge d'operator<<
    Par Linu6 dans le forum C++
    Réponses: 11
    Dernier message: 14/06/2008, 13h17
  5. Probleme de surcharge de flux
    Par BigBeni dans le forum C++
    Réponses: 20
    Dernier message: 01/05/2006, 19h10

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