CONNEXION
  • RetourJeux
    • Tests
    • Soluces
    • Previews
    • Sorties
    • Hit Parade
    • Les + attendus
    • Tous les Jeux
  • RetourActu
    • Culture Geek
    • Astuces
    • Réalité Virtuelle
    • Rétrogaming
    • Toutes les actus
  • RetourHigh-Tech
    • Actus JVTECH
    • Bons plans
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTECH
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch
    • Xbox Series
    • Overwatch 2
    • FUT 23
    • League of Legends
    • Genshin Impact
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • PS4
  • One
  • Switch
  • Wii U
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Etoile Abonnement RSS

Sujet : C# - Pb après suppression d'objet d'une collection

DébutPage précedente
1
Page suivantePage suivante
mojitow mojitow
MP
Niveau 4
07 janvier 2020 à 11:05:52

Bonjour,

je réalise un gestionnaire de contacts en C# dont voici l'interface :

https://www.noelshack.com/2020-02-2-1578390793-1.jpg

J'ai une fonction qui lors du clic sur le bouton "modifier" va récupérer les infos du contact sélectionné dans la ListBox, les transposer dans les champs texte correspondants, supprimer ce contact de la collection, puis réactiver le bouton "Ajout" afin d'ajouter le contact dont les infos ont été modifiées. La voici :

https://www.noelshack.com/2020-02-2-1578390998-thumbnail-20200107-104912.jpg

Cette fonction appelle une autre fonction qui va mettre à jour la ListBox en la vidant puis la remplissant de tous les contacts présents dans ma collection suite à un ajout, une modif ou une suppression de contact. La voici :

https://www.noelshack.com/2020-02-2-1578391109-thumbnail-20200107-104923.jpg

Mon problème est que lorsque je teste une modification, les infos du contact sélectionné sont bien transposées dans les champs texte, ce contact est bien supprimé de la collection mais suite à l'appel de majListe() la boucle foreach() continue à rechercher un contact qui du coup n'existe plus et le programme m'envoie l'erreur "System.InvalidOperationException : 'La collection a été modifiée ; l'opération d'énumération peut ne pas s'exécuter.'"

Quelqu'un aurait-il une idée d'où vient le problème ? je sèche :question:

Si besoin je peux mettre le code dans les balises.

PS: Je débute donc tous les commentaires constructifs sur mon code, indentation, etc... sont les bienvenus :)

Message édité le 07 janvier 2020 à 11:07:43 par mojitow
boucif boucif
MP
Niveau 24
07 janvier 2020 à 16:05:59

Bonjour

1) ne jamais supprimer ou ajouter un élément d'une liste pendant que tu la parcours

2) c'est pas la bonne façon de faire, pas besoin de supprimer et de remettre l'élément dans la liste, tu as juste à modifier les valeurs sur ton objet et comme ta liste contient une référence sur cet objet celui-ci sera à jour à l'intérieur.

boucif boucif
MP
Niveau 24
07 janvier 2020 à 16:13:40

3) j'avais pas vu ton lstcontact.selecteditem ==
tu peux faire plus simple et casté directement ton lstcontact.selecteditem en contact
ma préférence va au as pour les objets
https://coderwall.com/p/18dgtg/using-as-and-is-for-safe-casting-in-c

et tu peux copier/coller le code sur le site dans une citation si le block code marche pas, c'est plus simple pour nous qu'un screen

mojitow mojitow
MP
Niveau 4
10 janvier 2020 à 16:42:22

Salut Boucif,

1) Il me semblait que c'était foireux, je vais trouver un autre moyen.

2) En fait le prog est pour un TP et la prof demande qu'on supprime et recharge tous les contacts c'est pour cela.

3) Je vais me pencher sur les is / as afin de bien comprendre lequel s'adapte à quel cas.

Merci pour les réponses, je savais qu'en mettant "C#" dans le titre j'allais t'aggro :rire:

Message édité le 10 janvier 2020 à 16:43:09 par mojitow
boucif boucif
MP
Niveau 24
11 janvier 2020 à 00:27:42

Mdr c'est mon langage de prédilection voila + 10 ans que j'en fais :banzai:

l'idée c'est de supprimer les éléments après coup, en stockant les éléments à supprimer dans une autre liste dans ton foreach, et après parcourir cette nouvelle liste et supprimer dans la liste initiale par exemple (we ça peut être chiant), après il y a d'autre façon de faire je ne vais pas toutes te les énumérer

mojitow mojitow
MP
Niveau 4
13 janvier 2020 à 10:53:20

Du coup j'ai fait comme ca :
je stock l'indice du contact à modifier une fois trouvé dans la boucle, une fois la boucle terminée (je vais optimiser pour que ca boucle jusqu'à trouver le contact et non sur la liste entière) je supprime le contact, recharge la liste mise à jour dans la listbox puis l'utilisateur peut modifier les coordonnées du contact et l'ajouter à nouveau.

        // Evènement sur clic du bouton Modifier
        private void btnModifier_Click(object sender, EventArgs e)
        {
            // Si une ligne est bien sélectionnée
            if (lstContacts.SelectedIndex != -1)
            {
                // Stockage (via index) du contact à supprimer
                int index = 0;

                // Recherche dans la collection du contact sélectionné dans la listbox
                foreach (var contact in lesContacts)
                {
                    // MAJ des champs nom, prenom, tel avec les infos du contact sélectionné
                    if (lstContacts.SelectedItem.ToString().Equals(contact.infosContact()))
                    {
                        txtNom.Text = contact.getNom();
                        txtTel.Text = contact.getTel();
                        rdbPro.Checked = true;

                        if (contact is Particulier)
                        {
                            txtPrenom.Text = ((Particulier)contact).getPrenom();
                            rdbParticulier.Checked = true;
                        }

                        index = lesContacts.IndexOf(contact);
                    }
                }

                // Suppression du contact puis MAJ de la listbox et activation des champs
                // Pour nouvel ajout.
                lesContacts.RemoveAt(index);
                majListeSimple();
                enable(true);
            }
        }

Perso je débute, j'ai touché un peu au C++, java, C#, javascript, php et je préfère de loin utiliser le C# même si avec l'expérience je changerai peut-être d'avis.
Fuck le php.

boucif boucif
MP
Niveau 24
13 janvier 2020 à 21:57:59

J’ai fais un peu de java, bcp de c# et du js, php je veux même pas en entendre parler 🤣
En passant js aussi c’est merdique.
Je check ton code, je pense il y a plus simple

boucif boucif
MP
Niveau 24
13 janvier 2020 à 23:33:29
  public partial class Form1 : Form
    {
        List<Contact> lesContacts = new List<Contact>();
        public Form1()
        {
            InitializeComponent();


        }

        private void button1_Click(object sender, EventArgs e)
        {

            // Si une ligne est bien sélectionnée
            Contact contact = listBox1.SelectedItem as Contact;
            if (contact != null)
            {
                nomTextEdit.Text = contact.Nom;
                prenomTextEdit.Text = contact.Prenom;
                telTextEdit.Text = contact.Tel;
              
                lesContacts.Remove(contact);
                UpdateList();
            }
            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var c = new Contact()
            {
                Nom = nomTextEdit.Text,
                Prenom = prenomTextEdit.Text,
                Tel = telTextEdit.Text
            };
            lesContacts.Add(c);
            UpdateList();
        }

        private void UpdateList()
        {
            listBox1.Items.Clear();
            foreach (var item in lesContacts)
            {
                listBox1.Items.Add(item);
            }
        }
    }
  public class Contact
    {
        public string Nom { get; set; }
        public string Prenom { get; set; }
        public string Tel { get; set; }

        public override string ToString()
        {
            return $"{this.Nom} {this.Prenom}";
        }
    }

Button1 c'est modifier
Button2 c'est ajouter

TU peux travailler directement avec les objets étant donné que c'est la même référence à chaque fois
Il faut savoir qu'en C# (et je pense d'autre langage) tu as 2 types de donnée, les types valeurs et les types références
https://docs.microsoft.com/fr-fr/dotnet/csharp/language-reference/keywords/reference-types
https://blog.alphorm.com/type-valeur-et-type-reference-en-c/

C'est bon a connaitre mais pas sur que tu comprenne cette notion en tant que débutant mais très utile pour dev en c# de la meilleure façon possible.

mojitow mojitow
MP
Niveau 4
14 janvier 2020 à 16:43:55

Intéressant le cast avec le "as" effectivement ca simplifie les choses surtout qu'on ne se sert que d'un objet après et pas de plusieurs variables de types différents.

Sur le blog que tu as link,

il faut spécifier son type ou utiliser le mot clé var pour permettre au compilateur de déduire le type."

On peut déclarer toutes les variables en tant que var et le compilateur va déduire les types parfaitement derrière ? ca me parait gros :ouch2:

C'est super intéressant en tout cas les 2 types de variables existants et les répercussions sur la mémoire et donc la performance de l'appli.
Mais effectivement c'est un peu flou.

En gros ce que je comprends c'est que l'emplacement mémoire d'une variable de type valeur stock 1 donnée (1, "lol", etc...) tandis que celui d'une variable de type référence ne stock qu'une adresse. Mais les données sont bien stockées quelque part...ca implique donc 2 emplacements mémoire, 1 pour l'adresse du véritable stockage des données et 1 pour ce stockage ? Je n'y vois plus trop clair....

Je t'avoue que j'avais étudié le mot clé "ref" utilisé lors d'appels de fonctions avec certains paramètres et j'avais bien compris le principe mais là je ne sais plus quoi comprendre....

boucif boucif
MP
Niveau 24
14 janvier 2020 à 20:04:53

http://blog.algowin.fr/2018/10/29/csharp-pile-tas-memoire/

Oui t’étais pas loin, une fois que tu maitrises ces notions, tu fais du meilleur code, plus concis et plus juste en espérant que tu mettes pas le mot cle ref de partout 😂

thefearisback thefearisback
MP
Niveau 9
16 janvier 2020 à 03:12:46

Sinon tu mets juste un break après avoir modifier ta liste :(

DébutPage précedente
1
Page suivantePage suivante
Répondre
Prévisu
?
Victime de harcèlement en ligne : comment réagir ?
Infos 0 connecté(s)

Gestion du forum

Modérateurs : godrik, LGV
Contacter les modérateurs - Règles du forum

Sujets à ne pas manquer

La vidéo du moment