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 :

Passage par référence


Sujet :

C#

  1. #1
    Membre régulier

    Inscrit en
    Février 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 106
    Points : 71
    Points
    71
    Billets dans le blog
    1
    Par défaut Passage par référence
    Bonjour tous le monde,

    j'aimerai passer une classe par référence à une méthode qui détruit tous simplement cette classe et ses enfants,

    ceci se passe dans un environnement graphique et du coup cette méthode me sert a détruit les objets qui ne sont plus utilisables,

    la méthode est :

    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    public static void DisposeIGfxAndChild(IGfx igfx)
            {
                #region
                // supression d'un IGfx et de ses enfants
                if (igfx != null)
                {
                    // cast de l'objet
                    if (igfx.GetType() == typeof(Bmp))
                    {
                        Bmp b = igfx as Bmp;
                        b.Visible = false;
                        b.Child.Clear();
                    }
                    else if (igfx.GetType() == typeof(Rec))
                    {
                        Rec r = igfx as Rec;
                        r.Visible = false;
                        r.Child.Clear();
                    }
                    else if (igfx.GetType() == typeof(Anim))
                    {
                        Anim a = igfx as Anim;
                        a.Visible(false);
                        a.Close();       // arret de l'animation
                        a.img.Child.Clear();
                    }
     
                    // supression du parent
                    if (igfx.GetType() == typeof(Bmp))
                    {
                        (igfx as Bmp).Visible = false;
                        (igfx as Bmp).bmp = null;
                        igfx = null;
                    }
                    else if (igfx.GetType() == typeof(Anim))
                    {
                        (igfx as Anim).img.Visible = false;
                        (igfx as Anim).Close();
                        (igfx as Anim).img = null;
                        igfx = null;
                    }
                    else if (igfx.GetType() == typeof(Rec))
                    {
                        (igfx as Rec).Visible = false;
                        igfx = null;
                    }
                    else if (igfx.GetType() == typeof(Txt))
                    {
                        (igfx as Txt).Visible = false;
                        igfx = null;
                    }
                }
     
                // netoyage des list
                IGfxList.RemoveAll(f => f == null);
                #endregion
            }
    pour IGfx c'est une Interface pour les classes Bmp (Bitmap), Rec (Rectangle), Anim (Animation), Txt (Text) qui hèrite de cette interface

    donc quand j'appel la méthode DisposeIGfxAndChild avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    IGfx __PlayerStats = IGfxList.FindAll(f => f.GetType() == typeof(Rec) && (f as Rec).name == "__playerStatesInBattleRecParent");
    DisposeIGfxAndChild(__PlayerStats);
    la y a un truc qui ne passe pas comme je le souhaite, c'est que l'objet passé par référence ne se retire pas de la liste après l'avoir mis sur null
    c-à-d le code suivant :
    IGfxList.RemoveAll(f => f == null);
    ne supprime pas l'objet de la liste, et après débogage, l'objet passé par référence n'a pas subit de changement et n'est null, mais on dirai que c'est l'objet en cours qui est null, du coup aucune correspondance dans la liste IGfxList alors que l'objet existe toujours puisque je le trouve sous le nom "__playerStatesInBattleRecParent" mais pas null

    j'ai compris alors qu'il faut passer l'objet pas le mot clef Ref,
    chose faite et j'appel avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DisposeIGfxAndChild(ref __PlayerStats);
    et j'ai créée une surcharge de la méthode de destruction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public static void DisposeIGfxAndChild(Ref IGfx igfx)
            {
            ...
            }
    Erreur de compilation :
    Une propriété, un indexeur ou l'accès au membre dynamique ne peut pas être passé en tant que paramètre de sortie (out) ni de référence (ref)

    je pige rien, une idée svp ?

  2. #2
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Salut,

    tu ne peux pas passer by ref un élément d'une collection, et je suppose que IGfxList en est une.
    Plus je connais de langages, plus j'aime le C.

  3. #3
    Membre régulier

    Inscrit en
    Février 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 106
    Points : 71
    Points
    71
    Billets dans le blog
    1
    Par défaut
    ah ok, bon je vais le supprimer en le cherchons sur la collection et le supprimer directement

    merci pour l'info

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour

    Est -tu sur que ce code est fiable:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
     
    IGfx __PlayerStats = IGfxList.FindAll(f => f.GetType() == typeof(Rec) && (f as Rec).name == "__playerStatesInBattleRecParent");
    DisposeIGfxAndChild(__PlayerStats);
    PlayersStats est un List<IGfx> car IGfxList.FindAll() renvoit un list<IGfx)...
    Comme ta methode recoit un objet IGFx ca ne marche pas...
    j'aurais ecrit plutot:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
                 List<IGfx>  __PlayerStats = IGfxList.FindAll(f => f.GetType() == typeof(Rec) && (f as Rec).name == "__playerStatesInBattleRecParent");
     
                for (int i = 0; i < playerStats1.Count;i++ )
                {
                    DisposeIGfxAndChild(playerStats1[i]);
                }
                // netoyage des list
                IGfxList.RemoveAll(f => f == null);
    et dans ta methode simplement:
    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
     
     
     
    public static void DisposeIGfxAndChild(IGfx igfx)
            {
                #region
                // supression d'un IGfx et de ses enfants
                if (igfx != null)
                {
                    // cast de l'objet
                    if (igfx is Bmp)
                    {
                        Bmp b = igfx as Bmp;
                        b.Visible = false;
                        b.Child.Clear();
                        b=null
                    }
                    else if (igfx is Rec)
                    {
                        Rec r = igfx as Rec;
                        r.Visible = false;
                        r.Child.Clear();
                     r=null;
                    }
                    else if (igfx is Anim)
                    {
                        Anim a = igfx as Anim;
                        a.Visible(false);
                        a.Close();       // arret de l'animation
                        a.img.Child.Clear();
                        a=null;
                    }
     
     
                }
     
              #endregion
            }
    bon code...

  5. #5
    Membre régulier

    Inscrit en
    Février 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 106
    Points : 71
    Points
    71
    Billets dans le blog
    1
    Par défaut
    oui en effet c'est une liste, c'est juste une erreur de copie,

    mais le problème été pareil, du coup j'ai un autre soucie la

    disons que j'ai une liste d'élément, que j'aimerai faire un traitement dessus, et vus que la requête Sql passé est un peut longue j'ai fait une 2éme liste qui contiens les éléments ciblés pour un traitement rapide comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    List<Bmp> allPlayersExceptChallenged = AllPlayers.FindAll(f => f.Pseudo != ChallengeTo && f != myPlayer);
                        if(allPlayersExceptChallenged.Count >0)
                        {
                            for (int cnt = allPlayersExceptChallenged.Count; cnt > 0; cnt--)
                            {
                                allPlayersExceptChallenged[cnt - 1].Visible = false;
                                allPlayersExceptChallenged[cnt - 1] = null
                                allPlayersExceptChallenged.RemoveAt(cnt - 1);
                            }
                        }
    du coup la liste AllPlayers n'est pas modifié, ci comme ci la liste allPlayersExceptChallenged est un autre objet a part, je croyé que allPlayersExceptChallenged pointe vers AllPlayers mais visiblement ca créer un nouveau objet ?

  6. #6
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    Normalement ce code est bon et ta liste AllPLayers doit etre mise à jour car la 2eme liste pointe vers les memes objets que la liste d'origine...
    Je pense que ton probleme ne vient pas de ce bout de code ...
    Mais doit se situer dans un autre code ...
    Le AllPlayer du code poste n'est pas le bon AllPlayers ...

  7. #7
    Membre régulier

    Inscrit en
    Février 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 106
    Points : 71
    Points
    71
    Billets dans le blog
    1
    Par défaut
    Merci pour ta réponse MABROUKI mais après une étude sur le bout de code bah
    une liste qui pointe vers une autre liste après un trie grâce à une requête SQL ça crée une nouvelle liste mais qui contient les éléments de la liste trié.
    c-à-d que
    Liste<objet> L2 = L1.FindAll(Condition);

    L2 contiens les éléments de L1 selon la condition, un changement d'un élément sur la liste L2 affecte L1 (originale).

    MAIS

    si on supprime un élément de la lise L2 n'affecte pas la liste L1, du coup L1 contient toujours l'élément
    pour cela j'ai du placer ce code qui marche très bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // on supprime dépendamment du nom de l'objet 
    GfxTopList.RemoveAll(f => f.Name() == igfx.Name());
    au lieu de celui la
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // l'objet ne se supprime pas parce que l'élément originale ne se met pas à null,
    IGfxList.RemoveAll(f => f == null);
    donc la suppression par son nom ma résolue le problème
    et se que j'ai conclus c'est qu'une modification des éléments d'une autre liste se fait sans problème à part l'allocation d'un nouveau espace de mémoire (nouvelle instance d'après une doc MSDN) ou le mettre sur null (<-- je ne sais pas pourquoi )
    je cois

    en passons mes codes précédents ne sont pas vraiment ceux que j'utilise, c'est juste une ressemblance pour simplifier

  8. #8
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    Re
    OUPS !!! En fait ce l'absurdite de ce bout de coup de code m'a echappe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // netoyage des list
                IGfxList.RemoveAll(f => f == null);
    Car cette instruction recherche des elements qui -doivent etre null- c.à.d qui n'existe pas ce qui est ABSURDO..et ne fait strictement RIEN...
    En fait mes habitudes de code m'ont sauve car la reference des elements est "nullifie" dans les if de la methode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     if (igfx != null)
                {
                    // cast de l'objet
                    if (igfx is Bmp)
                    {
                        Bmp b = igfx as Bmp;
                        b.Visible = false;
                        b.Child.Clear();
                        b=null                }
    Evidemment si tu supprimes les elements en faisant reference à leur "name" ,alors FindAll recherche des elements qui EXISTENT(ne sont pas null) et qui satisfont la condition...

    Dans ton interface IGfx tu du aurais prevoir un prop ToDelete(un marqueur) ...
    Ensuite ta methode DisposeIGfxAndChild passe et marque tous les candidats à la mort par ToDelete et au retour de cette methode RemoveAll liquide tous les items marques...
    Enfin la manipulation de nombreuses listes qui sont liees doit etre regroupee dans une methode commune pour pouvoir les synchroniser (addition d'element ,suppression)....
    Bon code...

  9. #9
    Membre régulier

    Inscrit en
    Février 2009
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 106
    Points : 71
    Points
    71
    Billets dans le blog
    1
    Par défaut
    Si j'ai bien compris, si je les mis en null il ne sont plus considérés dans la liste ?
    donc une recherche ne donnera rien ?

    mais si non, faut que j'évite de les passez par null et me contenter de les supprimer par leur nom ?
    en faite j'hésite sur le faite de les mettre en null, je sais pas si le GAC va s'en occuper tous seul , je lui fait pas trop confiance

    si non ça dois clôturer le sujet.

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

Discussions similaires

  1. Passage par référence
    Par e1lauren dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 01/09/2006, 12h59
  2. Passage par copie vs passage par référence
    Par bolhrak dans le forum C++
    Réponses: 11
    Dernier message: 20/08/2006, 23h37
  3. Réponses: 4
    Dernier message: 26/12/2005, 17h01
  4. Passage par référence
    Par difficiledetrouver1pseudo dans le forum Langage
    Réponses: 9
    Dernier message: 28/09/2005, 11h17
  5. Problème très rapide de passage par référence
    Par Noxexplorer dans le forum ASP
    Réponses: 2
    Dernier message: 23/06/2005, 10h02

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