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 :

Parcours de listes de structures


Sujet :

C#

  1. #1
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut Parcours de listes de structures
    Bonjour à tous,

    une question me titille depuis quelque temps au sujet des collections de structs.
    Je m'explique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    List<MaStruct> list;
    foreach(MaStruct s in list)
    {
    int a = s.UnePropriété;
    }
     
    for(int i = 0 ; i < list.Count ; i++)
    {
    int a = list[i].UnePropriété;
    }
    Y'a-t-il copie de la struct dans un cas et pas dans l'autre ? dans le cas du foreach, il me semble que oui : si je modifie s dans le corps du foreach, la collection n'est pas altérée. Dans le cas du for, la ligne "list[i].UnePropriété = 0" lance une exception car visiblement l'indexeur this[int] de List renvoie un objet non modifiable (une rvalue, si je ne me trompe).

    J'ai un projet ou pour des raisons historiques, des objets qui devraient être des classes sont des structs, avec des dizaines de champs plus ou moins complexes. Et je finis par me demander si le parcours d'une collection de structs est intrinsèquement coûteux, ou s'il y a moyen de récupérer des valeurs sans pour autant recopier la struct en entier dans la mémoire associée à la fonction courante.

    En espérant avoir été clair
    ಠ_ಠ

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Guulh
    Dans le cas du for, la ligne "list[i].UnePropriété = 0" lance une exception car visiblement l'indexeur this[int] de List renvoie un objet non modifiable (une rvalue, si je ne me trompe).
    Pourtant ça devrait marcher (à moins que UnePropriété soit en lecture seule, mais dans ce cas ça ne compilerait pas...)
    C'est quoi l'exception ?

  3. #3
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Pourtant ça devrait marcher (à moins que UnePropriété soit en lecture seule, mais dans ce cas ça ne compilerait pas...)
    C'est quoi l'exception ?
    Je cite : Impossible de modifier les membres de 's', car il s'agit d'un 'variable d'itération foreach'

    Ce qui signifie que pour modifier une struct dans une liste, il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(int i = 0; i < liste.Count ; i++)
    {
    MaStruct s = liste[i]; // on copie
    s.UnePropriété = 0; // on modifie
    liste[i] = s; // on recopie
    }
    C'est aussi moche que peu performant
    ಠ_ಠ

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Tu sembles mélanger exception et erreur de compilation... une exception se produit pendant l'exécution.
    cf. la doc pour les erreurs du compilateur CS1654 (cas du foreach) et CS1612 (cas du for)
    Citation Envoyé par Guulh
    Ce qui signifie que pour modifier une struct dans une liste, il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(int i = 0; i < liste.Count ; i++)
    {
    MaStruct s = liste[i]; // on copie
    s.UnePropriété = 0; // on modifie
    liste[i] = s; // on recopie
    }
    C'est aussi moche que peu performant
    Oui, c'est moche... mais bon, c'était moche aussi d'utiliser des structures pour faire ce genre de chose

  5. #5
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Tu sembles mélanger exception et erreur de compilation... une exception se produit pendant l'exécution.
    cf. la doc pour les erreurs du compilateur CS1654 (cas du foreach) et CS1612 (cas du for)
    Certes, me suis mal exprimé Mais la doc de ces erreurs de compilation n'est ni explicite ni détaillée, malheureusement.

    Mais tu vois le fond du truc ? Quand tu fais une boucle for, tu ne vas voir le contenu de la liste que quand tu demandes à évaluer liste[i], alors que je ne sais pas ce qui se passe de le cas du foreach. Je me demande dans le ce cas, avec foreach(MaStruct s in liste), que est la nature exacte de l'objet s : ça n'a pas l'air d'être une variable puisque ce n'est pas modifiable, ça n'est peut être qu'un accesseur, mais je manque peut être de vocabulaire de programmation pour saisir ce que ça peut être.
    ಠ_ಠ

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Oui, je vois ce que tu veux dire...
    En fait, avec foreach, l'enumerateur de la collection te renvoie des copies des objets (puisqu'ils sont de type valeur et non référence). Par contre je ne vois pas trop pourquoi il dit que ce n'est pas une variable... peut-être qu'il génère cette erreur juste pour qu'on évite de faire l'erreur de modifier une copie ?

  7. #7
    Expert éminent
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Points : 7 660
    Points
    7 660
    Par défaut
    Citation Envoyé par Guulh Voir le message
    J'ai un projet ou pour des raisons historiques, des objets qui devraient être des classes sont des structs, avec des dizaines de champs plus ou moins complexes.
    Si les objets sont complexes, et donc probablement avec une taille importante, les structures ne sont plus adaptées. Les recommandations de Microsoft sont de 16 octets max je crois (2 entiers sur 64 bits par exemple).

    Maintenant peut être que cela a été fait pour utiliser le passage par valeur, plutôt que par référence. Mais même si au départ c'est historique, peut être faudrait-il envisager le passage à des classes, si c'est possible.
    Pas de questions techniques par MP

Discussions similaires

  1. liste chainée & structure
    Par hunter99 dans le forum C
    Réponses: 8
    Dernier message: 10/12/2006, 16h31
  2. les listes chaineés(structures)
    Par snakemetalgear dans le forum C
    Réponses: 18
    Dernier message: 14/11/2006, 18h09
  3. Récupération d'une liste de structures Oracle via Java
    Par MagikMarcel dans le forum Langage
    Réponses: 2
    Dernier message: 29/06/2006, 16h34
  4. Réponses: 7
    Dernier message: 18/04/2006, 17h44
  5. liste et structure
    Par dinver dans le forum C
    Réponses: 5
    Dernier message: 28/11/2005, 09h38

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