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 :

[C#] Pourquoi redéfinir les opérateurs en static ? [Débat]


Sujet :

C#

  1. #1
    Membre averti
    Avatar de rozwel
    Inscrit en
    Mars 2002
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 324
    Points : 334
    Points
    334
    Par défaut [C#] Pourquoi redéfinir les opérateurs en static ?
    Développeur Java pure souche à la base, je suis en train de découvrir C# à travers le document de Serge Tahé et j'en suis à la section sur la redéfinition des opérateurs. Le problème c'est que j'ai beaucoup de mal à comprendre la logique qui veut que les redéfinitions d'opérateurs soient déclarés statiques, avec comme premier paramètre une instance de la classe ou est redéfini l'opérateur. Est-ce que quelqu'un pourrait m'expliquer pourquoi les concepteurs du langage n'ont pas préféré une approche plus orientée objet qui aurait consisté à déclarer les redéfinitions d'opérateurs comme de simples méthodes d'instances ?

  2. #2
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    En quoi aurait-ce été une approche davantage orientée objet ?

  3. #3
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    Une methode static sur une classe, ce n'est jamais qu'une fonction. Il n'y a rien d'objet la dedans.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Je trouve au contraire que les méthodes static sont justement les fonctions classiques dans le concept objet. Si techniquement ce n'est rien de plus qu'une fonction, ça a une signification bien précise, en tout cas pour moi, et je les utilise bien sûr différement des fonctions.

    Une fonction est membre d'une classe, ce n'est pas rien, il y a une notion de portée (la méthode static peut accéder aux membres privés, mais vous allez sans doute me sortir le mot-clef friend).

  5. #5
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    Pas d'accord avec jab. C'est une fonction dans un espace de nom.
    D'un point de vue sémantique, la fonction statique a un lien fort avec la classe.
    D'un point de vue technique, pour y accéder, il faut préciser la classe. Il y a donc une partition en espace de nom, qui est importante en objet.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par jab
    Une methode static sur une classe, ce n'est jamais qu'une fonction. Il n'y a rien d'objet la dedans.
    Une méthode statique appartient à une classe. Une classe est un objet comme un autre. Il n'y a rien de non-OO là-dedans.

    Une méthode *globale* en revanche, là oui, ça n'a rien d'OO. Mais la seule façon de reproduire ça en .NET c'est avec un singleton (à consommer avec très grande modération donc), et les méthodes statiques ne sont pas limitées aux singletons (heureusement).

    Les opérateurs sont très bien au niveau des classes. Ils n'appartiennent pas à une instance donnée.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Points : 621
    Points
    621
    Par défaut
    Citation Envoyé par remram44
    JUne fonction est membre d'une classe, ce n'est pas rien, il y a une notion de portée (la méthode static peut accéder aux membres privés, mais vous allez sans doute me sortir le mot-clef friend).
    Accéder aux membre privés static uniquement.
    Sinon, il faut bien une instance de cette classe.
    ...

    Citation Envoyé par Maniak
    Une méthode *globale* en revanche, là oui, ça n'a rien d'OO. Mais la seule façon de reproduire ça en .NET c'est avec un singleton (à consommer avec très grande modération donc), et les méthodes statiques ne sont pas limitées aux singletons (heureusement).
    Je ne vois pas le rapport entre méthode globale et singleton.
    Un singleton permet d'avoir une instance unique. Ce n'est pas utile pour accéder à une méthode static.

  8. #8
    jab
    jab est déconnecté
    Rédacteur
    Avatar de jab
    Homme Profil pro
    SharePoint developpeur
    Inscrit en
    Février 2004
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : SharePoint developpeur
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 1 173
    Points : 4 339
    Points
    4 339
    Par défaut
    Je ne voulai pas dire que ce n'est pas OO et que ce n'est pas pratique, j'en utilise aussi souvent. C'est très utilisé par exemple en orienté service mais le concept OO de base c'est j'ai un objet et j'applique une action dessus. Avec une méthode static c'est un peu différent. Les propriétés que l'on accède doivent aussi être Static.
    Mais on ne va pas en débattre toute la nuit surtout par forum se serait trop fastidieux.

  9. #9
    Membre averti
    Avatar de rozwel
    Inscrit en
    Mars 2002
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 324
    Points : 334
    Points
    334
    Par défaut
    Surtout que la question de depart n'etait pas tant de savoir si static c'est objet ou pas que d'essayer de comprendre pourquoi on billou a decide de nous obliger a redefinir les operateurs avec une methode static alors que, dans ce cas precis, une methods d'instance nous aurait permis de nous passer de ce premier parametre redondant qui correspond en fait a la premier operande.

    Personnellement, cela m'aurait paru beaucoup plus intuitif que objet1+objet2 soit equivalent a objet1.operator+(objet2) plutot qu'a objet1.GetType().operator+(objet1,objet2), non ? (si tant est que ce soit bien GetType() la methode pour recuperer la classe d'une instance, je ne sais plus)

  10. #10
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    En même temps, si tu redéfinis les opérateurs, c'est pas pour faire object1.GetType().operator+(object1,object2), hein...

    Et .NET non plus ne fait pas ça. Quand tu compiles ton programme, le compilo sait quel est le type des objets mis en oeuvre dans les instructions faisant appels aux opérateurs.

    Y'a pas de différence entre le style Java ou c# à ce niveau là.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Points : 621
    Points
    621
    Par défaut
    Citation Envoyé par rozwel
    Surtout que la question de depart n'etait pas tant de savoir si static c'est objet ou pas que d'essayer de comprendre pourquoi on billou a decide de nous obliger a redefinir les operateurs avec une methode static alors que, dans ce cas precis, une methods d'instance nous aurait permis de nous passer de ce premier parametre redondant qui correspond en fait a la premier operande.
    Et si on fait nullptr + objet1, on appelle une méthode de l'objet nullptr évidemment.

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par jab
    mais le concept OO de base c'est j'ai un objet et j'applique une action dessus. Avec une méthode static c'est un peu différent. Les propriétés que l'on accède doivent aussi être Static.
    En jetant un coup d'oeil du côté de SmallTalk, la différence est assez vite gommée :
    Les membres non-statiques appartiennent à une instance d'une classe.
    Les membres statiques appartiennent à une instance d'une metaclasse.

    Les instances des classes sont les objets qu'on utilise habituellement.
    Les instances des metaclasses sont les classes elles-mêmes.

    C'est le niveau supérieur, mais le fonctionnement reste le même :)


    Citation Envoyé par NicolasG
    Je ne vois pas le rapport entre méthode globale et singleton.
    Les singletons sont utilisés pour reproduire (grosso modo) une variable globale. Variable globale qui peut donc avoir des méthodes, qui se trouvent donc être des méthodes globales :)

    Pour rejoindre ce qui est dit plus haut :
    Les méthodes d'un singleton sont les méthodes d'une instance (de classe) unique.
    Les méthodes statiques sont les méthodes d'une instance (de metaclasse) unique.

    La manière d'obtenir l'instance unique varie (de peu, un singleton utilise fatalement du statique quelque part :), mais le résultat est le même.

  13. #13
    Membre averti
    Avatar de rozwel
    Inscrit en
    Mars 2002
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 324
    Points : 334
    Points
    334
    Par défaut
    Citation Envoyé par davcha
    En même temps, si tu redéfinis les opérateurs, c'est pas pour faire object1.GetType().operator+(object1,object2), hein...

    Et .NET non plus ne fait pas ça. Quand tu compiles ton programme, le compilo sait quel est le type des objets mis en oeuvre dans les instructions faisant appels aux opérateurs.

    Y'a pas de différence entre le style Java ou c# à ce niveau là.
    En fait je pensais plus à la façon dont le CLR interprétait un opérateur, et même avec ta précision, je ne vois toujours pas l'intérêt de remonter d'un niveau jusqu'à la classe alors qu'on pourrait avoir la première opérande sous la main. Mais enfin bon. Là où ça pose une question chiante, c'est de savoir ce qui m'empêche de déclarer comme premier paramètre une classe qui n'a rien à voir avec celle dans laquelle l'opérateur est défini. Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public class Truc{
      public static Truc operator+(string s1, string s2){...}
    }
    Qu'est-ce qui nous empêche d'écrire ça? Et si rien ne nous en empêche, comment le compilateur identifie-t-il ce qu'il doit faire sur "bi"+"dule"? Question vraiment innocente.

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Points : 621
    Points
    621
    Par défaut
    Citation Envoyé par Maniak
    La manière d'obtenir l'instance unique varie (de peu, un singleton utilise fatalement du statique quelque part , mais le résultat est le même.
    Le résultat est bien similaire mais je me demande comment tu peux préférer écrire MaClasse.GetInstance().MaMethode() plutôt que MaClasse.MaMethode()
    Sans parler du codage de GetInstance()...

    Je n'ai encore jamais eu besoin de singleton en utilisant à la place les membres static.

  15. #15
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    Citation Envoyé par rozwel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public class Truc{
      public static Truc operator+(string s1, string s2){...}
    }
    Qu'est-ce qui nous empêche d'écrire ça? Et si rien ne nous en empêche, comment le compilateur identifie-t-il ce qu'il doit faire sur "bi"+"dule"? Question vraiment innocente.
    Oui, mais non. Tu n'as pas le droit d'écrire ça. L'un des deux paramètres doit être du type Truc.

    Citation Envoyé par NicolasG
    Le résultat est bien similaire mais je me demande comment tu peux préférer écrire MaClasse.GetInstance().MaMethode() plutôt que MaClasse.MaMethode()
    Sans parler du codage de GetInstance()...

    Je n'ai encore jamais eu besoin de singleton en utilisant à la place les membres static.
    Tu contrôles mieux ce que tu fais avec un singleton... Enfin bon... Disons que c'est plus "évident".

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par NicolasG
    Le résultat est bien similaire mais je me demande comment tu peux préférer écrire MaClasse.GetInstance().MaMethode() plutôt que MaClasse.MaMethode()
    Plutôt simplement .Instance ou .Current pour suivre ce qui se retrouve le plus souvent dans le framework. Et pour peu que ce soit utilisé plusieurs fois de suite, ça passe dans une variable locale, donc tout aussi simple à écrire :)
    (et on n'est pas à 3 touches près de toute façon)

    Citation Envoyé par NicolasG
    Sans parler du codage de GetInstance()...
    http://www.yoda.arachsys.com/csharp/singleton.html
    La 4è version est très bien, et le code est on ne peut plus bref :)

    Citation Envoyé par NicolasG
    Je n'ai encore jamais eu besoin de singleton en utilisant à la place les membres static. :D
    - en ASP.NET, à moins de faire un singleton qui est stocké en fait dans HttpContext.Current.Items, l'instance est partagée entre toutes les requêtes exécutées sur le serveur. Pas glop dans de nombreux cas
    - pas de polymorphisme avec les méthodes statiques
    - pas de moyen de remplacer l'instance par une version 'light' pour les tests

  17. #17
    Membre averti
    Avatar de rozwel
    Inscrit en
    Mars 2002
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 324
    Points : 334
    Points
    334
    Par défaut
    Citation Envoyé par NicolasG
    Le résultat est bien similaire mais je me demande comment tu peux préférer écrire MaClasse.GetInstance().MaMethode() plutôt que MaClasse.MaMethode()
    Sans parler du codage de GetInstance()...

    Je n'ai encore jamais eu besoin de singleton en utilisant à la place les membres static.
    Mais je n'ai jamais voulu avoir une GetInstance() justement c'est tout le contraire. Quand tu appliques un opérateur, tu l'appliques sur des instances non ? Donc l'opérande de gauche est déjà disponible, pas besoin de remonter au niveau de la classe pour récupérer une méthode statique de surcharge d'opérateur.

    Enfin bref apparemment on ne s'en sort pas, j'ai l'impression que c'est vraiment une question de perception. Moi ça me parait maladroit mais ça parait surement beaucoup plus naturel à ceux qui ont beaucoup travaillé avec des langages procéduraux (partiellement procéduraux comme C++) de considérer les surcharges d'opérateurs comme des méthodes de type librairie.

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Points : 621
    Points
    621
    Par défaut
    rozwel
    Citation Envoyé par rozwel
    Mais je n'ai jamais voulu avoir une GetInstance() justement c'est tout le contraire.
    Pas de panique, c'était une considération sur les singletons. Ca n'a rien à voir avec les surcharges d'opérateurs.

    Maniak
    Citation Envoyé par Maniak
    - en ASP.NET, à moins de faire un singleton qui est stocké en fait dans HttpContext.Current.Items, l'instance est partagée entre toutes les requêtes exécutées sur le serveur. Pas glop dans de nombreux cas
    Ok, si on a besoin de passer une instance unique à plusieurs objets, le singleton s'impose.
    Citation Envoyé par Maniak
    - pas de polymorphisme avec les méthodes statiques
    Désolé, c'est faux. Je l'ai vérifié en C# et en C++/CLI.
    Citation Envoyé par Maniak
    - pas de moyen de remplacer l'instance par une version 'light' pour les tests
    Là, je ne vois pas la différence.

  19. #19
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par rozwel
    Quand tu appliques un opérateur, tu l'appliques sur des instances non ?
    Tu réponds à ta propre question :)

    Un opérateur s'applique *sur* *des* instances.
    Ce n'est pas une opération effectuée *par* une instance, sur une autre.

    Quand tu appliques l'opérateur +, tu l'appliques sur deux instances, et tu en obtiens une troisième. L'opération n'appartient pas à une des deux premières instances.

    Citation Envoyé par rozwel
    Donc l'opérande de gauche est déjà disponible, pas besoin de remonter au niveau de la classe pour récupérer une méthode statique de surcharge d'opérateur.
    Faut savoir si tu veux gagner quelques caractères au niveau de la syntaxe, ou avoir un fonctionnement sémantiquement correct, correctement orienté objet et qui fonctionne correctement :)


    Allez, encore un exemple.
    Si l'opérateur + était affecté à une instance, ça reviendrait à une méthode Add.
    Si tu fais 'toto.Add( titi )', c'est pour ajouter titi à toto.
    Si tu fais 'tutu = toto + titi', c'est pour additionner toto et titi, et mettre le résultat dans tutu. Ni toto ni titi n'a le contrôle de l'opération. Ça n'a donc rien à faire au niveau d'une instance.


    (edit - gah, je hais cette option des smileys toujours décochée par défaut)

  20. #20
    Membre averti
    Avatar de rozwel
    Inscrit en
    Mars 2002
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 324
    Points : 334
    Points
    334
    Par défaut
    Voilà! Ca c'est logique !
    Pour autant on surcharge souvent l'opérateur + pour ajouter un élément à une liste par exemple. C'est le vice de la surcharge d'opérateurs. On peut l'utiliser pour faire des choses très différentes sémantiquement. En tout cas, voilà qui répond à ma question... et qui m'incite à ne jamais utiliser la surcharge d'opérateurs en C#

Discussions similaires

  1. Réponses: 8
    Dernier message: 03/11/2007, 18h01
  2. Redéfinir les marges d'une liste à puces
    Par om.rava dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 01/12/2005, 14h54
  3. question sur les opérateurs
    Par isidore dans le forum C++
    Réponses: 10
    Dernier message: 25/02/2005, 18h46
  4. [.NET] Pourquoi redéfinir la méthode dispose() d'une forme?
    Par Polyptyx dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 07/09/2004, 12h10
  5. les variables globales static
    Par gRRosminet dans le forum C
    Réponses: 8
    Dernier message: 27/04/2002, 08h34

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