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

VB.NET Discussion :

Initialiser un objet puis rompre le lien [Débutant]


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut Initialiser un objet puis rompre le lien
    Bonjour,

    Je suis actuellement confronté à un problème dont la solution doit être toute bête, mais dont je n'arrive pas à me dépêtrer.

    J'ai un fichier de sauvegarde dont je lie les donnée, ce qui me donne des objets obj1, obj2, etc... qui sont tous d'un type différent.

    Je crée un objet temporaire "obj_courant" que je voudrais initialiser à la valeur d'un des objet de départ, puis laisser l'utilisateur le modifier, et ensuite si les modification sont validées, le remettre dans l'objet qui sera sauvegardé.
    Mon problème est que lorsque je fais obj_courant=obj1 et que l'utilisateur modifie obj_courant, obj1 est modifié en même temps.

    Le problème vient sans doute du "=" qui crée un lien permanent entre les 2 objets, alors que je voudrais juste prendre les valeurs.
    Voici le code

    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
     
    dim obj1 as new maclasse1
    dim obj2 as new maclasse2
    dim obj_courant as object
    ...
     
    lecture_sauvegarde() 'lit un fichier de sauvegarde et affecte les valeurs dans obj1 et obj2
     
    objet_courant=nothing
    object_courant=new maclasse1
    objet_courant=obj1 'je veux récupérer les valeurs de obj1 et les mettre dans obj_courant
     
    modification_objet_courant_classe1() 'l'utilisateur travaille sur l'objet courant de type classe1
     
    if validation(obj_courant) then 'si les modification sont acceptées
     
    obj1=objet_courant 'on modifie obj1
    sauvegarde(obj1) ' et on le sauvegarde
    end if
     
     
    object_courant=nothing
    objet_courant = new maclasse2
    objet_courant=obj2
     
    modification_objet_courant_classe2() 'l'utilisateur travaille sur l'objet courant de type classe2
     
    if validation(obj_courant) then 'si les modification sont acceptées
     
    obj2=objet_courant 'on modifie obj2
    sauvegarde(obj2) ' et on le sauvegarde
    end if

  2. #2
    Membre Expert Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Par défaut
    Au delà que se soit tout bête... C'est la BASE de la programmation objet.

    VB.NET est Objet, (presque) TOUT est Objet.

    Donc si tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    dim obj_courant as TypeObjet
    Dim obj1 as TypeObjet
     
    obj_courant=obj1
    en réalité, objet_courant ET obj1, ne sont QUE deux pointeurs qui pointent sur le même objet en mémoire.


    Ce que tu veux faire toi, c'est une copie des données, le = au niveau objet ne te sera d'aucune aide.
    Deux solutions :

    - Créer une procédure qui copiera les valeurs de toutes les propriétés (string, integer) une à une, d'un objet à un autre.
    - Sinon, rendre la classe <Clonable> (ainsi que toute sous classe imbriqués).

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Je me doutais bien que mon problème venait du fait qu'on ne manipule que des pointeurs sur l'objet.
    Par contre je pensais qu'il existait une méthode qui permet de copier l'intégralité d'un objet dans un objet de même type.
    J'ai cherché des copie, des clonage, etc...
    Le cloneable semble être relativement limité, puisqu'il ne descend pas au sous-propriété

    De plus, si je dois écrire une méthode de clonage moi même, il en faut une différente par classe, horreur

    C'est le genre de limitation qui me fait enrager sur vb.net
    Du coup, je pense prendre une solution "sale" en sérializant mes objets, et en désérializant dans l'objet temporaire...

  4. #4
    Membre Expert Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Par défaut
    Ce n'est pas une limitation de VB.NET.

    Je ne connais aucun langage où on fait obj1 = obj2 qui fasse un clonage (deep) des données d'un objet...

    De plus VB.NET propose les interfaces ICloneable, il suffit de chercher un tout petit peu, c'est même intéressant à faire ET TRÈS SIMPLE.

    https://msdn.microsoft.com/fr-fr/lib...v=vs.110).aspx

    Je dirai même... GRACE a VB.NET, c'est facile.

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    lu en diagonale

    iclonable pourrait etre une solution, quand on l'implémente on doit coder ce qu'on y fait
    souvent ca équivaut en effet à une recopie des propriétés du 1er niveau
    il y a d'ailleurs une méthode pour faire ca, memberwiseclone de mémoire

    après rien n’empêche de faire de la récursivité si tu as beaucoup de classe, et tu peux avoir du code générique avec la reflection (analyse des classes à l'exécution)


    sinon il me semblait avoir vue une interface à une époque qui permet de faire du transactionnel, mais si elle existe je n'ai plus son nom
    si elle n'existe pas rien n'empeche de coder le même comportement, sachant que si elle existe de toute facon on doit coder tout aussi ^^
    le principe d'une transaction c'est d'enregistrer un état de départ, et à la fin d'un traitement de valider (commit) ou non (rollbak) les modifications apportées
    là aussi sur plusieurs niveau ca doit pouvoir se simplifier (en nombre de ligne de code, pas en technicité) avec la reflection


    sinon voir si les structures te conviendraient, là ce n'est pas un pointeur qui est mit dans les variables, mais directement la valeur (sur x octets consécutifs)


    je viens de voir que tu évoques la sérialisation, je n'y vois rien de sale
    la sérialisation binaire peut avoir des effets imprévus car elle garde les références (peu d'impact sur une sérialisation simple, c'est plus pour des gros blocs entiers, c'est même parfois un avantage)
    la sérialisation xml ne me semble pas avoir ce comportement, donc un coup de serialize/deserialize et tu auras une copie
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2013
    Messages : 44
    Par défaut
    Citation Envoyé par mactwist69 Voir le message
    Ce n'est pas une limitation de VB.NET.

    Je ne connais aucun langage où on fait obj1 = obj2 qui fasse un clonage (deep) des données d'un objet...

    De plus VB.NET propose les interfaces ICloneable, il suffit de chercher un tout petit peu, c'est même intéressant à faire ET TRÈS SIMPLE.

    https://msdn.microsoft.com/fr-fr/lib...v=vs.110).aspx

    Je dirai même... GRACE a VB.NET, c'est facile.
    Je suis d'accord que ce n'est pas si compliqué, mais après des jours de lutte sur les datagridview, ce genre de choses à reconstruire par soi-même avec des fonctions relativement technique est usant.

    Même sur MSDN il invite à passer par des chemins détournés:

    Sérialiser l'objet de manière complète copié et puis restaurer les données sérialisées à une variable d'objet différent.
    Utilisez la réflexion avec la récursivité pour effectuer l'opération de copie complète.
    Je suis très intéressé par la notion de transaction, mais c'est pareil, pas facile de trouver cela quand on est débutant.

    Pour l'honneur, une petite fonction de clonage qui permet de faire ce que je voulais:



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Public Function clone(ByVal objet As Object) As Object
            Dim mem As New System.IO.MemoryStream()
            Dim binFormat As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
     
            'Sérialisation de l'objet dans le flux-mémoire
            binFormat.Serialize(mem, objet)
     
            'On se repositionne au début du flux-mémoire
            mem.Seek(0, System.IO.SeekOrigin.Begin)
     
            'Désérialisation de l'objet depuis le flux-mémoire vers l'objet renvoyé par la fonction
            clone = binFormat.Deserialize(mem)
        End Function

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

Discussions similaires

  1. [VBA-E]Rompre les liens vers un classeur
    Par la-breche dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 23/03/2007, 12h02
  2. Réponses: 10
    Dernier message: 13/09/2006, 09h13
  3. Réponses: 7
    Dernier message: 29/03/2006, 21h41
  4. Réponses: 5
    Dernier message: 19/11/2005, 18h53
  5. [servlet] initialisation d'objets
    Par tiPouick dans le forum Servlets/JSP
    Réponses: 11
    Dernier message: 05/08/2003, 12h12

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