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#]Comment surcharger l'opérateur [] ?


Sujet :

C#

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Points : 286
    Points
    286
    Par défaut [C#]Comment surcharger l'opérateur [] ?
    Bonjour à tous,
    Je débutte en C# et je n'arrive pas à créer une surcharge de l'opérateur [] afin d'utiliser un objet que j'ai créé tel que ceci Je ne veux evidemment pas créer un tableau de MonObjet mais seulement accéder aux différents élément de mon objet qui est une sorte de tableau.

    Est-ce possible et si oui, comment?

    Merci d'avance,
    Nicolas

  2. #2
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    tu parles de celà ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public virtual string this[int row,int col]
    {
    }

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Points : 286
    Points
    286
    Par défaut
    Heuuu...
    Je n'en ai aucune idée, je vais tester
    Pourquoi virtual au fait?

  4. #4
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Pour pas grand chose, c'est juste une habitude que j'ai prise afin de permettre aux classes qui héritent de la première de redéfinir le membre

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Points : 286
    Points
    286
    Par défaut
    Ok, merci beaucoup pour tes informations, c'est exactement ce que je cherchais
    Tant que j'y suis, si avec cette méthode je retourne un objet "Cell", comment pourrais je faire, si c'est possible, pour pouvoir écrire un code comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonObj[x, y] = 1;
    int val = MonObjet[x, y];
    Je dois redéfinir l'opérateur de cast int -> cell et cell -> int ou l'opérateur = ?

  6. #6
    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 NicolasJolet
    Ok, merci beaucoup pour tes informations, c'est exactement ce que je cherchais
    Tant que j'y suis, si avec cette méthode je retourne un objet "Cell", comment pourrais je faire, si c'est possible, pour pouvoir écrire un code comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonObj[x, y] = 1;
    int val = MonObjet[x, y];
    Je dois redéfinir l'opérateur de cast int -> cell et cell -> int ou l'opérateur = ?
    Si MonOj[x,y] est un objet, ça me paraît plus simple de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonObj[x, y].Value = 1;
    int val = MonObjet[x, y].Value;

  7. #7
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Citation Envoyé par NicolasG
    Si MonOj[x,y] est un objet, ça me paraît plus simple de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonObj[x, y].Value = 1;
    int val = MonObjet[x, y].Value;
    Dans certains cas oui, dans d'autres non

    Sinon pour répondre à la question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public virtual string this[int row,int col]
    {
     get
     {
        return code_pour_obtenir_cell(row,col);
      }
     set
     {
       code_pour_defnir_cell(row,col,value);
      }
    }
    Ensuite tu pourra faire directement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    monObjet[row,col] = Une_Valeur;

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Points : 286
    Points
    286
    Par défaut
    En fait j'utilise déja la méthode décrite par NicolasG, mais j'aimerai quand même essayer, même si ca n'a pas un grand intéret, de faire comme je l'ai dit.
    La méthode décrite par smyley correspond plus à ce que je cherche mais il y a un problème : je dois obligatoirement obtenir un objet cell lorsque je fais un monObj[x, y] car je dois pouvoir utiliser des méthodes de cet objet ainsi qu'accéder à ses propriétés.

  9. #9
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Citation Envoyé par NicolasJolet
    La méthode décrite par smyley correspond plus à ce que je cherche mais il y a un problème : je dois obligatoirement obtenir un objet cell lorsque je fais un monObj[x, y] car je dois pouvoir utiliser des méthodes de cet objet ainsi qu'accéder à ses propriétés.
    Oulà
    En fait la solution c'est que l'objet cell soit une classe, c'est tout car dans ce cas modifier l'objet dans l'accésseur le modifie également dans l'objet original. Imaginons ceci :

    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
     
    class Cell
    {
      public int value;
    }
     
    class Test
    {
     
    Cell[,] cells = new Cell[10,2];
     
    public virtual Cell this[int row,int col]
    {
     get
     {
     if(cells[row,col] == null)
       cells[row,col] = new Cell();
      return cells[row,col];
     }
    }
     
    }
     
    /* pour modifier value */
    Test test = new Test();
    test[0,1].value = 12;
    Conclusion : value a été modifié également dans l'objet original, c'est ça ce qu'il y a de bien avec les class : c'est comme des poiteurs

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Points : 286
    Points
    286
    Par défaut
    Mais heuu, vous allez vraiment me donner l'impression que je ne sais pas m'exprimer (comment c'est le cas?!)
    On va mettre des petits exemples plutôt que d'utiliser des noms génériques et je vais aussi expliquer ma façon de faire (surement bizarre, je vous l'accorde )
    Je suis en train de créer une classe SudokuGrid. Par extention, je développe aussi une classe SudokuCell.
    J'aurais très bien pu définir un tableau de SudokuCell dans mon SudokuGrid mais j'ai préféré utiliser un tableau d'int de 9*9(c'est en fait plus complexe que ca mais ca n'a pas d'intéret à être exposé ici).
    J'ai utilisé un tableau d'int histoire de gagner en rapidité. Je ne sais pas si dans le cas du C# celà joue mais je compte plus tard porter mes classes sans trop de changement en C++.

    Voici donc en résumé mes classes actuelles :
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    [Serializable]
        class SudokuCell
        {
            private int[, ,] tab;   // Référence sur le tableau de la classe SudokuGrid
            private int x, y;
     
            public SudokuCell(int[, ,] tab, int x, int y)  // TODO : voir si c une reference ou une copie
            {
                this.tab = tab;
                this.x = x;
                this.y = y;
            }
     
            public int Value
            {
                get
                {
                    return tab[x, y, 0];
                }
                set
                {                         
                      ...
             }
        }
     
        [Serializable]
        class SudokuGrid
        {
            // Tableau pour enregistrer les possibilités de chaque case
            private int[, ,] tab = new int[9, 9, 13];     // 1ere dim : x, 2eme dim : y, 3eme dim : 0 = la valeur de la case, 1->9 = nombre d'occurences de la valeur, 10 : nombre de valeurs possibles, 11 : seule valeur possible si existe sinon valeur de la case, 12 : 0 = normal, 1 = case init
     
            public SudokuGrid()
            {
               ...
            }      
     
            public SudokuCell this[int x, int y]
            {
                get
                {
                    return new SudokuCell(tab, x, y);
                }              
            }
     
            #region "Serialisation"
    ...
            #endregion
        }
    J'aimerai donc pouvoir retourner mon objet SudokuCell comme je le fais pour l'instant avec [x, y], mais également pouvoir effectuer la mm opération que le .Value mais sans le .Value. Je ne sais pas si je suis très clair

    Merci de vous intéresser à mon problème

  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
    A vrai dire, je ne vois pas l'utilité d'utiliser une classe SudokuCell dans ce code.

    Si l'indexeur par défaut (this[x,y]) n'est utilisé que pour manipuler des entiers, autant retourner une référence vers le tableau avec z=0.

    Il est toujours possible de définir des méthodes pour accéder aux autres attributs de cellule (z>0).
    Par exemple this[x,y,EnumAttributCellule] (à vérifier).

    Ceci dit, une classe SudokuCell est parfaitement justifiée si elle gère les données et d'autres fonctions liées comme l'affichage d'une donnée.
    Dans ce cas, il ne faut pas utiliser un tableau int[x,y,z] mais un tableau SudokuCell[x,y].

    Pour le portage en C++, sur un sujet comme celui-là, je ne suis pas convaincu que le gain en performance soit significatif.
    Commencer par construire une structure objet cohérente et penser ensuite à l'optimisation des sections de code utilisées intensivement, c'est la méthode recommandée.
    Donc, vive l'objet et à bas les tableaux à 3 dimensions.

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 413
    Points : 286
    Points
    286
    Par défaut
    En fait ma classe SudokuCell fait plus que de simplement contenir des entiers. Elle propose des fonctionnalités et propriétés comme : savoir si une valeur peut-être valide pour cette case, le nombre de possibilités restantes, si la case est une case d'init (qui ne peut être ni effacée ni modifiée, ...)
    Je doute quand même que niveau rapidité, le fait d'accéder à des objets pour remettre à jour ses propriétés comme le nombre de valeurs possibles, le nombre d'occurences d'une valeur pour une cellule, ... soit plus rapide ou équivalent que d'accéder à un tableau.
    Il est toujours possible de définir des méthodes pour accéder aux autres attributs de cellule (z>0).
    Par exemple this[x,y,EnumAttributCellule] (à vérifier).
    A la base c'était ma classe SudokuGrid qui gérait ça de cette manière. J'avais donc fait des méthodes qui encapsulaient la gestion du tableau mais ça revenait à celà. Le problème, c'est que je ne trouvais pas propre de passer en paramètre x et y pour chaque méthode. C'est pour celà que j'ai utilisé la classe SudokuCell.

    Mais c'est vrai que faire un new à chaque accès de this[x,y] demande peut-être autant de temps que de faire un accès à un tableau d'objets

    Quelqu'un sait-il s'il y a une méthode meilleure qu'une autre pour gagner en rapidité? (Je pense que NicolasG a déja son avis, mais les autres ) (Et ceci dit je pense que je vais utiliser un tableau d'objet si personne ne me dit qu'il y a moyen de faire plus rapide car mon code sera beaucoup plus compréhensible et facile à modifier)

    EDIT : après essai, je me rends compte que dans l'histoire il y a un détail qui a son importance que je n'ai pas cité : un objet SudukoCell n'est pas indépendant d'un autre! Lorsque je met à jour la Valeur d'une SudokuCell, je dois aussi pouvoir accéder aux cases du même carré, de la même ligne et de la même colonne.

    PS : peut-être devrais-je créer un nouveau post pour cette question?

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

Discussions similaires

  1. Comment surcharger l'opérateur () ?
    Par Avatar36 dans le forum C++
    Réponses: 7
    Dernier message: 12/05/2015, 11h21
  2. Réponses: 1
    Dernier message: 09/03/2010, 09h56
  3. Réponses: 3
    Dernier message: 02/03/2010, 08h16
  4. [C#] Tri d'objet et surcharge d'opérateur
    Par Royd938 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 17/12/2007, 00h26
  5. [VB .NET] Surcharge d'opérateur
    Par Franckintosh dans le forum VB.NET
    Réponses: 2
    Dernier message: 07/09/2004, 19h05

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