none
Explication érroné! RRS feed

  • Question

  •     Bonjour à tous, 
        Pour  mon premier post sur ce forum, je me permets  de signaler une erreur sur le msdn ou sur le probleme que je vais dévelloper.
        En effet, je suis actuellement sur le dévellopement d'un projet personnel et je désirais réaliser une classe englobant une collection. Voulant me renseigner sur les différentes possibilités des collections et des différents objets en dérivants, j'ai consulté le msdn sur ce sujet.
    J'ai eu le déplaisir de constater que les exemples ne correspondent en rien avec la réalisation:
        En effet les exemples d'implémentation d'interface proposent des méthodes publics alors que l'implémentation réelle de celle-ci ne le permet pas.
        Donc, est-ce une erreur du msdn ou de l'implémentation?!
    Si l'erreur se situe au niveau du msdn, je trouve dommage et rébarbatif de réécrire deux fois les mêmes méthodes, une fois pour l'implémentation et une fois pour utiliser la collection.
    vendredi 1 mai 2009 18:38

Réponses

  • Bonjour,

    Vous devez confondre entre l'implémentation explicite et implicite de l'interface.
    Lorsqu'une classe implémente une interface, il est possible d'implémenter les méthodes de cette interface soit de façon explicite, soit de manière implicite (ou le mélange des deux).

    De manière implicite :
    Les méthodes sont publiques au niveau de la classe, il est possible d'appeler ces méthodes directement sur une variable du type de la classe.

    Implémentation :
    public void RemoveAt(int index)
    {
         ...
    }
    MaClasseQuiImplementIList c;
    


    c = new MaClasseQuiImplementIList()
    c.RemoveAt(5);
    De manière explicite :
    Les méthodes ne sont pas visibles sur les variables de type classe (cela provoque une erreur de compilation) mais uniquement sur les variables du type de l'interface (Il n'y a pas de niveau de visibilité, c'est un un niveau "public" un peu spécial) :
    void IList.RemoveAt(int index)
    {
         ...
    }
    MaClasseQuiImplementIList c;
    


    c = new MaClasseQuiImplementIList()
    c.RemoveAt(5); //Erreur de compilation


    ((IList)c).RemoveAt(5);

    De manière générale on utilise toujours l'implémentation implicite (classique en POO). Exceptionnellement, les cas où l'on utilise l'implémentation explicite sont les suivantes :

    • Lorsqu'une classe ne supporte pas une fonctionnalité d'une méthode. (Par exemple une liste en lecture seule, on ne veut pas que l'utilisateur de la classe puisse appeller la méthode Remove() et RemoveAt()). Dans ce cas, on implémente explicitement ces méthodes et déclenchant une exception de type NotImplementedException(). Ainsi, l'utilisateur vera que la classe ne dispose pas de méthode RemoveAt() et Remove(). Cependant, il peut appeler ces méthodes en typant explicitement sa variable en type de l'interface, dans ce cas l'exception sera déclenchée.
    • En cas de conflit de méthode de 2 interfaces : Par exemple, si votre classe implémente IEnumerable<T> et IEnumerable, ces 2 dernières dipose d'une méthode qui s'appelle GetEnumerator(). Toutes les 2 ne renvoient pas le même type d'objet (l'une IEnumerator<T>, l'autre IEnumerator). Pour résoudre ce conflit, on implémente une méthode de façon explicite et l'autre de façon implicite. Et le plus souvent, la méthode qui est implémentée implicitement fait appel à la méthode qui est implémentée explicitement (ou l'inverse).

    Cordialement


    Gilles TOURREAU - MVP C#
    dimanche 3 mai 2009 08:01
    Modérateur

Toutes les réponses

  • Es-ce que tu pourrais nous donner un lien vers le site MSDN où tu as vus cette information? Et je ne suis pas sur de comprendre ton problème, tu veux créé une classe contenant une collection? Es-ce que tu veux créer un nouveau type de collection dérivant d'une interface?
    Microsoft MVP C# :: mongeon.devrpm.ca
    vendredi 1 mai 2009 19:00
    Modérateur
  • Je met le lien vers l'exemple fourni pour IList:

    ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.fr/fxref_mscorlib/html/adf6745d-affe-7d6c-2cba-2d9d22ff0521.htm

    Les méthodes et propriétés cité ne remplissent pas les conditions d'implémentation de IList!
    En effet, toutes celles-ci sont public alors que pout l'implémentation elles doivent être sans indication de portée et donc private.
    Ce que, en soit, je trouve dommage. Cela oblige à écrire deux fois ces methodes et propriétés.

    PS: La collection est fortement type par un objet que j'ai créer(Collection<Bonus>). J'ai demandé à l'IDE (VS2008) de mettre les méthode à implémenter de maniere explicite.
    vendredi 1 mai 2009 19:35
  • Bonjour,

    Vous devez confondre entre l'implémentation explicite et implicite de l'interface.
    Lorsqu'une classe implémente une interface, il est possible d'implémenter les méthodes de cette interface soit de façon explicite, soit de manière implicite (ou le mélange des deux).

    De manière implicite :
    Les méthodes sont publiques au niveau de la classe, il est possible d'appeler ces méthodes directement sur une variable du type de la classe.

    Implémentation :
    public void RemoveAt(int index)
    {
         ...
    }
    MaClasseQuiImplementIList c;
    


    c = new MaClasseQuiImplementIList()
    c.RemoveAt(5);
    De manière explicite :
    Les méthodes ne sont pas visibles sur les variables de type classe (cela provoque une erreur de compilation) mais uniquement sur les variables du type de l'interface (Il n'y a pas de niveau de visibilité, c'est un un niveau "public" un peu spécial) :
    void IList.RemoveAt(int index)
    {
         ...
    }
    MaClasseQuiImplementIList c;
    


    c = new MaClasseQuiImplementIList()
    c.RemoveAt(5); //Erreur de compilation


    ((IList)c).RemoveAt(5);

    De manière générale on utilise toujours l'implémentation implicite (classique en POO). Exceptionnellement, les cas où l'on utilise l'implémentation explicite sont les suivantes :

    • Lorsqu'une classe ne supporte pas une fonctionnalité d'une méthode. (Par exemple une liste en lecture seule, on ne veut pas que l'utilisateur de la classe puisse appeller la méthode Remove() et RemoveAt()). Dans ce cas, on implémente explicitement ces méthodes et déclenchant une exception de type NotImplementedException(). Ainsi, l'utilisateur vera que la classe ne dispose pas de méthode RemoveAt() et Remove(). Cependant, il peut appeler ces méthodes en typant explicitement sa variable en type de l'interface, dans ce cas l'exception sera déclenchée.
    • En cas de conflit de méthode de 2 interfaces : Par exemple, si votre classe implémente IEnumerable<T> et IEnumerable, ces 2 dernières dipose d'une méthode qui s'appelle GetEnumerator(). Toutes les 2 ne renvoient pas le même type d'objet (l'une IEnumerator<T>, l'autre IEnumerator). Pour résoudre ce conflit, on implémente une méthode de façon explicite et l'autre de façon implicite. Et le plus souvent, la méthode qui est implémentée implicitement fait appel à la méthode qui est implémentée explicitement (ou l'inverse).

    Cordialement


    Gilles TOURREAU - MVP C#
    dimanche 3 mai 2009 08:01
    Modérateur
  • Bonjour,

    Merci de cette réponse explicite!!

    C'est effectivement le cas. En demandant l'implémentation explicite je ne me suis pas rendu compte de sa portée.
    Ce cas est vraiment spécifique et ne correspond pas à mes attentes.
    Je corrigerai donc mon code en conséquence!

    Encore merci m'avoir éclairer sur ce point.

    lundi 11 mai 2009 22:02