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 :

Affectation et objet


Sujet :

C#

  1. #1
    Membre averti
    Inscrit en
    Juillet 2004
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 47
    Par défaut Affectation et objet
    Salut,

    Je me suis mis il y a peu au C# pour un projet, et je doit malheureusement coder comme avec les autres langages, ce qui me porte tord, et il y a des choses que je ne comprend avec C#.

    J'ai une fonction qui doit me ramener un objet.
    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
    private Boolean getElemNear(out IFeature fRet,IPoint Px)
            {
                double distMin;
                double dist;
                Boolean bRet=false;
     
                ........
                fRet = null;
                IFeature feature = fCursor.NextFeature();
                .........
                IProximityOperator proximityOperator = Px as IProximityOperator;
                while (feature != null)
                {
                    // Recherche distance mini
                    dist = proximityOperator.ReturnDistance(feature.Shape);
                    if (dist<distMin)
                    {
                        distMin = dist;
                        fRet=feature;
                        bRet = true;
                    }
                    feature = fCursor.NextFeature();
                }
                return bRet;
            }
    Le problème vient de fRet=feature. Je pensais recopier un objet dans un autre objet. Mais non ! On se retrouve avec 2 pointeurs qui localisent le même objet.
    Résultat, fRet pointe toujours sur 'null', et je ne trouve pas comment faire pour copier cet objet dans ma variable de retour !

    Il faut savoir que :
    - Il n'y a pas de fonction clone dans cet objet.
    - pas de duplication dans le contructeur
    - les fonctions 'serialize' ne sont pas disponible pour ce framework !

    Comment puis-je faire ?
    Merci.

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2008
    Messages
    337
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 337
    Par défaut
    Voici un tuto sympa.

  3. #3
    Membre averti
    Inscrit en
    Juillet 2004
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 47
    Par défaut
    Citation Envoyé par hotsizzle Voir le message
    Voici un tuto sympa.
    Oui, je l'ai vu. Mais la classe IFeature ne peut pas être modifié pour l'interface ICloneable.
    Une copie superficielle n'est pas possible en plus, car elle contient d'autres objets en cascade. C'est une sorte de super classe.

    Me voila bien embêté !

  4. #4
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Salut,
    Il est probable que mon manque de sommeil me fait passer à coté de quelque chose mais pour moi le code est bon (enfin presque, mais vu que le code est incomplet je ne suis pas sûr que le problème que je vois ne soit pas traité ailleurs).
    Disons plutôt que je vois un problème mais il est probable qu'il soit corrigé dans une partie manquante.

    Je parle du distMin : il n'est pas affecté avant l'entrée dans la boucle.
    Comme il s'agit d'un type de valeur ca signifie qu'il y a 0 dedans. Résultat il y a fort à parier que le if (dist < distMin) soit toujours faux, et donc fRet n'est jamais affecté et conserve donc le null présent en début de code.

    Est-tu passé en pas à pas dans ta boucle pour vérifier si fRet est affecté à un moment et auquel cas si son affectation se déroule bien ?
    Parce que pour moi, les interfaces étant des types de références, fRet est effectivement un pointeur et il n'y à pas de copie de valeur, pour autant il devrait bel et bien pointé sur le dernier objet IFeature pour lequel la condition était vrai.

  5. #5
    Membre averti
    Inscrit en
    Juillet 2004
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 47
    Par défaut
    Du coté du calcul de distance et du test, tout est correcte.
    Lors du deboggage, fRet prend bien la valeur en cours du premier test, mais dès que je lit le prochain élément, fRet prend aussitôt la valeur de ce nouvelle élément, même sans passé par le bloc de teste.
    Le 'NextFeature()' réécrit dans la même zone mémoire sur le feature, et fRet pointant sur le même emplacement mémoire, il devient identique et perd la valeur prise lors du test.
    Du coup, quand feature est null, fRet pointe sur une zone qui n'existe pas, et les données sont toutes erronées à l'intérieur.

    Si tu veut, voila la procédure complète :
    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
     
            private Boolean getElemNear(out IFeature fRet,IPoint Px)
            {
                double distMin;
                double dist;
                Boolean bRet=false;
     
                ILayer layer = getLayerByName("Canalisation catégorie actuelle");
     
                ISegmentCollection pSegColl = new PolygonClass();
                pSegColl.SetCircle(Px, 100);
     
                ISpatialFilter sFilter = new SpatialFilterClass();
                Polygon poly = pSegColl as Polygon;
                sFilter.Geometry = poly as IGeometry;
                sFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                IFeatureLayer fLayer=layer as IFeatureLayer;
                IFeatureCursor fCursor = fLayer.Search(sFilter, true);
                IFeature feature = fCursor.NextFeature();
                distMin = 3000000;
                fRet = null;
                IProximityOperator proximityOperator = Px as IProximityOperator;
                while (feature != null)
                {
                    // Recherche distance mini
                    dist = proximityOperator.ReturnDistance(feature.Shape);
                    if (dist<distMin)
                    {
                        distMin = dist;
                        fRet=feature;
                        bRet = true;
                    }
                    feature = fCursor.NextFeature();
                }
                return bRet;
            }

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    D'après la doc de l'API que t'utilises, le deuxième argument de la méthode Search, de type booléen, indique si la méthode doit ou pas recycler les objets renvoyés par le curseur. Passe le à false, et ça devrait aller mieux

  7. #7
    Membre averti
    Inscrit en
    Juillet 2004
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 47
    Par défaut [Résolu]
    Citation Envoyé par Guulh Voir le message
    D'après la doc de l'API que t'utilises, le deuxième argument de la méthode Search, de type booléen, indique si la méthode doit ou pas recycler les objets renvoyés par le curseur. Passe le à false, et ça devrait aller mieux
    En effet, mon problème est réglé.
    Mais je reste perplexe quand même sur le fonctionnement de copie d'objet...

    Merci.

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par pconrad Voir le message
    En effet, mon problème est réglé.
    Mais je reste perplexe quand même sur le fonctionnement de copie d'objet...

    Merci.
    C'est simple, faut juste s'y faire
    En C#, il existe deux types d'objets : les types valeur et les types référence. Les un sont des class, les autres des struct. Les mots clé sont les mêmes qu'en C++, mais la séparation class/struct de C# n'a rien à voir avec C++ (ou la seule différence entre les deux est la visibilité par défaut des membres).

    Les types référence ne sont manipulables que par référence, d'où le nom. Donc quand tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A a = new A(); A b = a;
    a et b référencent le même objet.
    L'opérateur = ne fait jamais de copie de classes. Si tu veux une copie d'une classe C#, il te faut coder une méthode (comme Clone()) ou un constructeur par copie, par exemple.

    Par contre, pour les structs,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A a = new A(); A b = a;
    b et a sont deux objets distincts, et b est initialisé (copié) à partir de A.

    Donc grosso modo les classes C# se comportent comme des pointeurs C++, et les struct comme des objets.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 12/01/2011, 19h03
  2. affectation des objets
    Par TaymouWan dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 03/08/2009, 17h58
  3. [POO] affecter un objet de type file à un autre
    Par slash_X dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 26/02/2009, 10h06
  4. Affectation d'objet
    Par docv266 dans le forum Langage
    Réponses: 1
    Dernier message: 07/08/2007, 13h22
  5. Réponses: 2
    Dernier message: 29/10/2003, 23h47

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